Bugfixes:
BaseTimeBetweenFilter.validate()now returnsFalseon invalid input instead of raising an exception.- Fix encoding for editing file in FileAdmin. Now it uses UTF-8 and accepts non-ASCII characters.
- SQLAlchemy backend:
conv_ARRAYnow infers the array element'spython_typeand passes it through as theSelect2TagsFieldcoercecallable. Saving a PostgresARRAY(Integer)/ARRAY(Float)column no longer fails withcolumn "x" is of type integer[] but expression is of type text[](closes #1724). - Fix sorting arrow direction in admin list view. Now it reflects the current sorting state (closes #2933).
- MongoEngine fileadmin backend: downloading GridFS files now preserves their name and extension instead of saving them as
file(closes #2916). - MongoEngine backend: stop reading the deprecated
GridOut.contentTypeproperty. File downloads and list/form widgets now resolve the MIME type viametadata["content_type"], the GridFS document directly (for legacy data), or filename-based guessing (closes #2920). - MongoEngine backend:
QueryAjaxModelLoader.formatnow handles unresolvedDBRefvalues gracefully instead of crashing withAttributeError: 'DBRef' object has no attribute 'pk'(which surfaced as HTTP 500 from the autocomplete endpoint when aReferenceFieldtarget was deleted). Broken references are shown as(missing: <collection>/<id>)so users can clear them (closes #2917). - Peewee backend: inline model forms now support
form_extra_fieldswhen the child form is autogenerated. Previously, inline forms ignored these fields because they bypassedget_form()and calledmodel_form()directly. - SQLAlchemy backend: the
Uniquevalidator now resolves its session when it runs instead of capturing the session that was active when the form was scaffolded. With flask-sqlalchemy-lite, forms scaffolded inside a startupapp_context()previously kept querying that context'sSession, which was never committed, rolled back or closed, so one connection per process sat "idle in transaction" after the first save of a form with a unique column (and failed permanently withPendingRollbackErroronce the server dropped it). BothModelView(Model, db)and the deprecatedModelView(Model, db.session)continue to work (relates to #2831). - Peewee backend:
ModelView.get_one()now returnsNonewhen no record matches, instead of letting peewee'sDoesNotExistpropagate. Requesting the details, edit or delete view for an absent or malformedidno longer returns HTTP 500; it flashes "Record does not exist." and redirects, matching the other backends (closes #2924).
Type hints:
- Type hints added to all functions and methods (some still use
typing.Anywhere full typing not yet available) - Updated InlineBaseFormAdmin.get_form() to return type[BaseForm] | None rather than T_MODEL_VIEW | None
- Minor type hinting improvements for peewee backend
- Admin(index_view=...) now accepts a BaseView instance rather than AdminIndexView, allowing e.g. FileAdmin