diff --git a/doc/changelog.rst b/doc/changelog.rst index 10f0fd54f..428f89632 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -8,6 +8,8 @@ Fixes: * 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` 2.0.0a0 ------- diff --git a/flask_admin/contrib/sqla/form.py b/flask_admin/contrib/sqla/form.py index a645653ae..9883fed3e 100644 --- a/flask_admin/contrib/sqla/form.py +++ b/flask_admin/contrib/sqla/form.py @@ -366,7 +366,7 @@ def conv_Boolean(self, field_args, **extra): @converts("Date") def convert_date(self, field_args, **extra): - field_args["widget"] = form.DatePickerWidget() + field_args.setdefault("widget", form.DatePickerWidget()) return fields.DateField(**field_args) @converts("DateTime") # includes TIMESTAMP diff --git a/flask_admin/tests/sqla/test_form.py b/flask_admin/tests/sqla/test_form.py new file mode 100644 index 000000000..735484def --- /dev/null +++ b/flask_admin/tests/sqla/test_form.py @@ -0,0 +1,54 @@ +import inspect +from unittest.mock import MagicMock + +import pytest +import wtforms +from wtforms.fields.simple import StringField + +from flask_admin.contrib.sqla.form import AdminModelConverter + +sqla_admin_model_converters = [ + method_name + for method_name, method in inspect.getmembers(AdminModelConverter) + if getattr(method, "_converter_for", None) +] + + +class TestAdminModelConverter: + @pytest.mark.parametrize("method_name", sqla_admin_model_converters) + def test_can_override_widget(self, method_name): + converter = AdminModelConverter(None, None) + + def fake_widget(*args, **kwargs): + return "
widget overridden
" + + class TestForm(wtforms.Form): + pass + + # Find out if field takes `name` or `_name` - depends on wtforms version. + # Required for python3.8 tests + argspec = inspect.signature(StringField.__init__).parameters + name_field = "name" if "name" in argspec else "_name" + + # Build args to pass to wtforms Field instance - mostly fake data, the only + # important thing is the fake widget. `_form` and name_field are required + # to get a 'bound' field instance that can be rendered. + field_args = { + "_form": TestForm(), + name_field: "field", + "widget": fake_widget, + "validators": [], + } + + field = getattr(converter, method_name)( + field_args=field_args, + column=MagicMock(), + ) + + # Some non-wtforms fields (eg `Select2TagsField` don't allow setting this field + try: + field.data = None + except AttributeError: + pass + + assert field() == "widget overridden
"