Skip to content

Commit

Permalink
Merge pull request #2551 from pallets-eco/fix/wtforms-3.2
Browse files Browse the repository at this point in the history
Add compatibility for wtforms 3.2+
  • Loading branch information
samuelhwilliams authored Oct 26, 2024
2 parents 9552b27 + c0c63b4 commit 0bf7f8b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 8 deletions.
1 change: 1 addition & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changelog

Fixes:

* 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.
Expand Down
16 changes: 16 additions & 0 deletions flask_admin/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,19 @@ def as_unicode(s):
def csv_encode(s):
"""Returns unicode string expected by Python 3's csv module"""
return as_unicode(s)


def _iter_choices_wtforms_compat(val, label, selected):
"""Compatibility for 3-tuples and 4-tuples in iter_choices
https://wtforms.readthedocs.io/en/3.2.x/changes/#version-3-2-0
"""
from packaging.version import Version
import wtforms

wtforms_version = Version(wtforms.__version__)

if wtforms_version >= Version("3.2.0"):
return val, label, selected, {}

return val, label, selected
13 changes: 10 additions & 3 deletions flask_admin/contrib/sqla/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from wtforms.utils import unset_value
from wtforms.validators import ValidationError

from flask_admin._compat import _iter_choices_wtforms_compat
from flask_admin._compat import iteritems
from flask_admin._compat import string_types
from flask_admin._compat import text_type
Expand Down Expand Up @@ -111,10 +112,14 @@ def _get_object_list(self):

def iter_choices(self):
if self.allow_blank:
yield ("__None", self.blank_text, self.data is None)
yield _iter_choices_wtforms_compat(
"__None", self.blank_text, self.data is None
)

for pk, obj in self._get_object_list():
yield (pk, self.get_label(obj), obj == self.data)
yield _iter_choices_wtforms_compat(
pk, self.get_label(obj), obj == self.data
)

def process_formdata(self, valuelist):
if valuelist:
Expand Down Expand Up @@ -174,7 +179,9 @@ def _set_data(self, data):

def iter_choices(self):
for pk, obj in self._get_object_list():
yield (pk, self.get_label(obj), obj in self.data)
yield _iter_choices_wtforms_compat(
pk, self.get_label(obj), obj in self.data
)

def process_formdata(self, valuelist):
self._formdata = set(valuelist)
Expand Down
11 changes: 8 additions & 3 deletions flask_admin/form/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from wtforms import fields

from flask_admin._compat import _iter_choices_wtforms_compat
from flask_admin._compat import as_unicode
from flask_admin._compat import text_type
from flask_admin.babel import gettext
Expand Down Expand Up @@ -146,13 +147,17 @@ def __init__(

def iter_choices(self):
if self.allow_blank:
yield ("__None", self.blank_text, self.data is None)
yield _iter_choices_wtforms_compat(
"__None", self.blank_text, self.data is None
)

for choice in self.choices:
if isinstance(choice, tuple):
yield (choice[0], choice[1], self.coerce(choice[0]) == self.data)
yield _iter_choices_wtforms_compat(
choice[0], choice[1], self.coerce(choice[0]) == self.data
)
else:
yield (
yield _iter_choices_wtforms_compat(
choice.value,
choice.name,
self.coerce(choice.value) == self.data,
Expand Down
8 changes: 6 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ deps =
-r requirements/tests.txt
commands_pre =
noflaskbabel: pip uninstall -y flask-babel
commands = pytest -v --tb=short --basetemp={envtmpdir} flask_admin/tests {posargs}
commands =
pip freeze
pytest -v --tb=short --basetemp={envtmpdir} flask_admin/tests {posargs}

[testenv:py38-min]
deps = -r requirements-skip/tests-min.txt
commands = pytest -v --tb=short --basetemp={envtmpdir} flask_admin/tests -W 'default::DeprecationWarning' {posargs}
commands =
pip freeze
pytest -v --tb=short --basetemp={envtmpdir} flask_admin/tests -W 'default::DeprecationWarning' {posargs}

[testenv:style]
deps = pre-commit
Expand Down

0 comments on commit 0bf7f8b

Please sign in to comment.