Changelog
=========

[unreleased]
------------------

Bugfixes:

* ``BaseTimeBetweenFilter.validate()`` now returns ``False`` on 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_ARRAY`` now infers the array element's ``python_type`` and passes it through as the ``Select2TagsField`` ``coerce`` callable. Saving a Postgres ``ARRAY(Integer)`` / ``ARRAY(Float)`` column no longer fails with ``column "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.contentType`` property. File downloads and list/form widgets now resolve the MIME type via ``metadata["content_type"]``, the GridFS document directly (for legacy data), or filename-based guessing (closes #2920).
* MongoEngine backend: ``QueryAjaxModelLoader.format`` now handles unresolved ``DBRef`` values gracefully instead of crashing with ``AttributeError: 'DBRef' object has no attribute 'pk'`` (which surfaced as HTTP 500 from the autocomplete endpoint when a ``ReferenceField`` target 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_fields`` when the child form is autogenerated. Previously, inline forms ignored these fields because they bypassed ``get_form()`` and called ``model_form()`` directly.
* Peewee backend: ``ModelView.get_one()`` now returns ``None`` when no record matches, instead of letting peewee's ``DoesNotExist`` propagate. Requesting the details, edit or delete view for an absent or malformed ``id`` no 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 using `typing.Any` where 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

2.2.0
------------------

New Features:

* SQLAlchemy filter classes (``FilterEqual``, ``FilterLike``, etc.) now accept a dotted-path string for the ``column`` argument (e.g. ``FilterEqual(column="author.email", name="Author Email")``); the path is resolved against the view's model and the necessary joins are added automatically.

Bugfixes:

* Fix a bug in v2.1.0 that caused UnboundLocalError in flask_admin.contrib.sqla.ModelView when an exception was raised during a create or update operation

2.1.0
-----

Deprecations:

* Deprecate ModelView(Model, db.session) in favor of ModelView(Model, db): https://github.com/pallets-eco/flask-admin/pull/2717

New Features:

* Flask-SQLAlchemy-Lite support: https://github.com/pallets-eco/flask-admin/pull/2789
* Add page title header with icon above every view via new {% block page_title %}: https://github.com/pallets-eco/flask-admin/pull/2706
* Upgrade bundled Bootstrap from 4.2.1 to 4.6.2 and remove unminified files: https://github.com/pallets-eco/flask-admin/pull/2787
* Flash error message on form validation failure (“Failed to create/save record”): https://github.com/pallets-eco/flask-admin/pull/2738

Bugfixes:

* Fix CSS class on column headers (dots replaced with dashes e.g.: col-user.email → col-user-email): https://github.com/pallets-eco/flask-admin/pull/2730
* Return HTTP 403 instead of 500 when inaccessible_callback returns None: https://github.com/pallets-eco/flask-admin/pull/2793
* FileAdmin: show empty date instead of 1970-01-01 when directory has no timestamp: https://github.com/pallets-eco/flask-admin/pull/2721
* Fix “Save & Add Another” using non-relative redirect URL (broke behind reverse proxies): https://github.com/pallets-eco/flask-admin/pull/2716

Others:

* Improved examples, tests, type hints

2.0.2
-----

* Adds support for Python 3.14: https://github.com/pallets-eco/flask-admin/pull/2685
* Adds a MenuDivider item for bootstrap themes: https://github.com/pallets-eco/flask-admin/pull/2696
* Field errors are now shown in red text for bootstrap themes: https://github.com/pallets-eco/flask-admin/pull/2699

2.0.1
-----

* Fix documentation
* Update arabic translations

2.0.0
-----

Breaking changes:

* Removed support for Python <3.10
* Use of the `boto` library has been replaced by `boto3`. S3FileAdmin and S3Storage now accept an `s3_client` parameter taking a `boto3.client('s3')` instance rather than `aws_access_key_id`, `aws_secret_access_key`, and `region` parameters.
* Azure Blob Storage SDK has been upgraded from the legacy version (v2) to the latest version (v12). AzureFileAdmin now accept `blob_service_client` rather than `connection_string` to give more flexibility with connection types.
* Flask-BabelEx is no longer supported; the package is no longer maintained and Flask-Babel is recommended/active instead.
* Mongoengine support in Flask-Admin no longer uses Flask-Mongoengine, as that library is no longer actively maintained.
* Bootstrap2 and Bootstrap3 themes are no longer available.
* `Admin()` now takes a `theme` parameter that encapsulates all of the configuration options for theming the admin instance. This replaces the `template_mode` parameter.
* All remaining Flask-Admin config has been namespaced under `FLASK_ADMIN_`.

.. list-table:: Configuration Changes
   :widths: 50 50
   :header-rows: 1

   * - Config variable name
     - What's changed
   * - FLASK_ADMIN_SWATCH
     - Removed; use `Theme(swatch=...)` instead
   * - FLASK_ADMIN_FLUID_LAYOUT
     - Removed; use `Theme(fluid=...)` instead
   * - MAPBOX_MAP_ID
     - Renamed to FLASK_ADMIN_MAPBOX_MAP_ID
   * - MAPBOX_SEARCH
     - Renamed to FLASK_ADMIN_MAPBOX_SEARCH
   * - MAPBOX_ACCESS_TOKEN
     - Renamed to FLASK_ADMIN_MAPBOX_ACCESS_TOKEN
   * - GOOGLE_MAPS_API_KEY
     - Renamed to FLASK_ADMIN_GOOGLE_MAPS_API_KEY
   * - DEFAULT_CENTER_LAT
     - Renamed to FLASK_ADMIN_DEFAULT_CENTER_LAT
   * - DEFAULT_CENTER_LONG
     - Renamed to FLASK_ADMIN_DEFAULT_CENTER_LONG
   * - ADMIN_RAISE_ON_INTEGRITY_ERROR
     - Renamed to FLASK_ADMIN_RAISE_ON_INTEGRITY_ERROR
   * - ADMIN_RAISE_ON_VIEW_EXCEPTION
     - Renamed to FLASK_ADMIN_RAISE_ON_VIEW_EXCEPTION

New functionality:

* Added support for Python <=3.13
* The default query for pymongo can be overridden
* Flask async routes are supported
* Flask-Admin now supports the `host_matching` mode of Flask apps. See documentation for how to configure this where needed.
* Flask-Admin is now compatible with SQLAlchemy v2+, Flask v3+, WTForms v3+, and Pillow v10+.
* Flask-Admin now declares its dependencies and supported dependency versions more cleanly, including using pip extras. If you use Flask-Admin with SQLAlchemy, for example, you should use `pip install flask-admin[sqlalchemy]` or list `flask-admin[sqlalchemy]` in your requirements.txt or pyproject.toml files.
* Apps using content security policies to restrict the assets that can be loaded can now whitelist Flask-Admin's assets by passing a `csp_nonce_generator` function to the Admin instance. See examples or documentation for how to configure this where needed.
* `page_size_options` can now be configured on Admin models, to restrict the page sizes that users can select. These are now enforced properly and cannot be bypassed by URL hacking.

Fixes:

* Bootstrap menu icons should show up properly and not duplicated
* Redis CLI commands are now case insensitive
* SQLAlchemy boolean filters now convert "1" and "0" to Python booleans, which fixes a type coercion issue with psycopg(3).
* Jinja templates can now be loaded in StrictUndefined mode.
* Remove an implicit dependency on `packaging`
* Fixed an error caused by the fallback implementation of `gettext()` (when used in templates)
* Fixes compatibility with WTForms 3.2+.
* The `Apply` button for filters will show/hide correctly again
* Fix `translations_path` attribute when Flask-Admin is used with Flask-Babel
* Some translation updates.
* Date fields no longer override `widget` if set in `form_args`
* “Save and Continue Editing” button no longer discards the “return URL” (allowing to retain filters when switching back to the list)

Misc:

* Translations and docs have been updated
* Various type hinting improvements and fixes

1.6.1
-----

* SQLAlchemy 2.x support
* General updates and bug fixes
* Dropped WTForms 1 support

1.6.0
-----

* Dropped Python 2 support
* WTForms 3.0 support
* Various fixes

1.5.8
-----

* SQLAlchemy 1.4.5+ compatibility fixes
* Redis CLI fixes

1.5.7
-----

* Bootstrap 4 support!
* Added hook for custom SQLAlchemy models initializers
* SQLAlchemy 1.4/2.0 compatibility fix

1.5.6
-----

* SQLAlchemy 1.3.6 compatibility fix
* Python 3.8 support

1.5.5
-----

* Werkzeug 1.0 compatibility fix
* Use fa-circle-o icon for unchecked booleans
* A few SQLAlchemy-related bug fixes

1.5.4
-----

* Fix display of inline x-editable boolean fields on list view
* Add support for several SQLAlchemy-Utils data types
* Support searching on SQLAlchemy hybrid properties
* Extra URL paramaters are now propagated to the next page when searching / filtering
* Add enum34 dependency when running on legacy Python version
* Update Mapbox API v1 URL format
* Update jQuery and moment dependencies in templates
* Fixed a datepicker issue, where only dates up to 2015 were showing up
* Updated Pillow dependency version

1.5.3
-----

* Fixed XSS vulnerability
* Support nested categories in the navbar menu
* SQLAlchemy
    * sort on multiple columns with `column_default_sort`
    * sort on related models in `column_sortable_list`
    * show searchable fields in search input's placeholder text
    * fix: inline model forms can now also be used for models with multiple primary keys
    * support for using mapped `column_property`
* Upgrade Leaflet and Leaflet.draw plugins, used for geoalchemy integration
* Specify `minimum_input_length` for ajax widget
* Peewee: support composite keys
* MongoEngine: when searching/filtering the input is now regarded as case-insensitive by default
* FileAdmin
    * handle special characters in filename
    * fix a bug with listing directories on Windows
    * avoid raising an exception when unknown sort parameter is encountered
* WTForms 3 support

1.5.2
-----

* Fixed XSS vulnerability
* Fixed Peewee support
* Added detail view column formatters
* Updated Flask-Login example to work with the newer version of the library
* Various SQLAlchemy-related fixes
* Various Windows related fixes for the file admin

1.5.1
-----

* Dropped Python 2.6 support
* Fixed SQLAlchemy >= 1.2 compatibility
* Fixed Pewee 3.0 compatibility
* Fixed max year for a combo date inline editor
* Lots of small bug fixes

1.5.0
-----

* Fixed CSRF generation logic for multi-process deployments
* Added WTForms >= 3.0 support
* Flask-Admin would not recursively save inline models, allowing arbitrary nesting
* Added configuration properties that allow injection of additional CSS and JS dependencies into templates without overriding them
* SQLAlchemy backend
  - Updated hybrid property detection using new SQLAlchemy APIs
  - Added support for association proxies
  - Added support for remote hybrid properties filters
  - Added support for ARRAY column type
* Localization-related fixes
* MongoEngine backend is now properly formats model labels
* Improved Google App Engine support:
  - Added TextProperty, KeyProperty and SelectField support
  - Added support for form_args, excluded_columns, page_size and after_model_update
* Fixed URL generation with localized named filters
* FileAdmin has Bootstrap 2 support now
* Geoalchemy fixes
  - Use Google Places (by default) for place search
* Updated translations
* Bug fixes

1.4.2
-----
* Small bug fix release. Fixes regression that prevented usage of "virtual" columns with a custom formatter.

1.4.1
-----

* Official Python 3.5 support
* Customizable row actions
* Tablib support (exporting to XLS, XLSX, CSV, etc)
* Updated external dependencies (jQuery, x-editable, etc)
* Added settings that allows exceptions to be raised on view errors
* Bug fixes

1.4.0
-----

* Updated and reworked documentation
* FileAdmin went through minor refactoring and now supports remote file systems. Comes with the new, optional, AWS S3 file management interface
* Configurable CSV export for model views
* Added overridable URL generation logic. Allows using custom URLs with parameters for administrative views
* Added column_display_actions to ModelView control visibility of the action column without overriding the template
* Added support for the latest MongoEngine
* New SecureForm base class for easier CSRF validation
* Lots of translation-related fixes and updated translations
* Bug fixes

1.3.0
-----

* New feature: Edit models in the list view in a popup
* New feature: Read-only model details view
* Fixed XSS in column_editable_list values
* Improved navigation consistency in model create and edit views
* Ability to choose page size in model list view
* Updated client-side dependencies (jQuery, Select2, etc)
* Updated documentation and examples
* Updated translations
* Bug fixes
