WTForms 3.3.1__tar.gz → 3.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wtforms-3.3.1 → wtforms-3.3.2}/CHANGES.rst +9 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/PKG-INFO +4 -1
- {wtforms-3.3.1 → wtforms-3.3.2}/README.rst +3 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/__init__.py +1 -1
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/fields/list.py +2 -3
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_list.py +47 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/.gitignore +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/LICENSE.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/Makefile +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/_static/logo_joined.svg +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/_static/logo_split.svg +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/_static/logo_square.svg +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/changes.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/conf.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/contributing.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/crash_course.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/csrf.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/ext.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/faq.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/fields.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/forms.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/i18n.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/index.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/license.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/make.bat +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/meta.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/specific_problems.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/validators.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/whats_new.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/docs/widgets.rst +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/hatch_build.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/pyproject.toml +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/_compat.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/csrf/__init__.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/csrf/core.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/csrf/session.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/datalist.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/fields/__init__.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/fields/choices.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/fields/core.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/fields/datetime.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/fields/form.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/fields/numeric.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/fields/simple.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/form.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/i18n.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/README.md +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ar/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ar/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/bg/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/bg/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ca/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ca/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/cs_CZ/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/cs_CZ/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/cy/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/cy/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/de/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/de/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/de_CH/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/de_CH/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/el/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/el/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/en/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/en/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/es/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/es/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/et/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/et/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/fa/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/fa/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/fi/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/fi/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/fr/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/fr/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/he/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/he/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/hu/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/hu/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/it/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/it/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ja/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ja/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/kk/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/kk/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ko/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ko/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/nb/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/nb/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/nl/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/nl/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/pl/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/pl/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/pt/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/pt/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ro/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ro/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ru/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ru/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/sk/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/sk/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/sr/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/sr/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/sv/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/sv/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ta/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/ta/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/tr/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/tr/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/uk/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/uk/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/wtforms.pot +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/zh/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/zh/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/zh_TW/LC_MESSAGES/wtforms.mo +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/locale/zh_TW/LC_MESSAGES/wtforms.po +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/meta.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/utils.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/validators.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/widgets/__init__.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/src/wtforms/widgets/core.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/__init__.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/common.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/conftest.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/__init__.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_boolean.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_button.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_color.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_custom.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_date.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_datetime.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_datetimelocal.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_decimal.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_defaults.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_field.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_file.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_filters.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_flags.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_float.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_form.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_hidden.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_html5.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_integer.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_label.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_month.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_password.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_radio.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_select.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_selectmultiple.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_string.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_submit.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_textarea.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_time.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/fields/test_week.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/test_csrf.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/test_datalist.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/test_form.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/test_i18n.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/test_locale_babel.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/test_webob.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/test_widgets.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/__init__.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_anyof.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_data_required.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_date_range.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_disabled.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_email.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_equal_to.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_input_required.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_ipaddress.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_lazy_proxy.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_length.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_mac_address.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_noneof.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_number_range.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_optional.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_readonly.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_regexp.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_url.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_uuid.py +0 -0
- {wtforms-3.3.1 → wtforms-3.3.2}/tests/validators/test_validators.py +0 -0
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
.. currentmodule:: wtforms
|
|
2
2
|
|
|
3
|
+
Version 3.3.2
|
|
4
|
+
-------------
|
|
5
|
+
|
|
6
|
+
Released 2026-11-01
|
|
7
|
+
|
|
8
|
+
- Fix nested :class:`~fields.FieldList` entries getting the old index of
|
|
9
|
+
their parent entry when they are appended after the parent list
|
|
10
|
+
renumbers its entries. :issue:`948`
|
|
11
|
+
|
|
3
12
|
Version 3.3.1
|
|
4
13
|
-------------
|
|
5
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: WTForms
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.2
|
|
4
4
|
Summary: Form validation and rendering for Python web development.
|
|
5
5
|
Project-URL: Documentation, https://wtforms.readthedocs.io
|
|
6
6
|
Project-URL: Changes, https://wtforms.readthedocs.io/changes
|
|
@@ -92,6 +92,8 @@ with frameworks even better.
|
|
|
92
92
|
framework, based on the features of Flask-WTF.
|
|
93
93
|
- `Bootstrap-Flask`_ Bootstrap-Flask is a collection of Jinja macros
|
|
94
94
|
for Bootstrap 4 & 5 and Flask using Flask-WTF.
|
|
95
|
+
- `WTForms-htmx`_ Interactive WTForms forms with no hand-written
|
|
96
|
+
JavaScript, powered by htmx and dark magic.
|
|
95
97
|
|
|
96
98
|
.. _Flask-WTF: https://flask-wtf.readthedocs.io/
|
|
97
99
|
.. _WTForms-Alchemy: https://wtforms-alchemy.readthedocs.io/
|
|
@@ -99,6 +101,7 @@ with frameworks even better.
|
|
|
99
101
|
.. _WTForms-Bootstrap5: https://github.com/LaunchPlatform/wtforms-bootstrap5
|
|
100
102
|
.. _Starlette-WTF: https://github.com/muicss/starlette-wtf
|
|
101
103
|
.. _Bootstrap-Flask: https://github.com/helloflask/bootstrap-flask
|
|
104
|
+
.. _WTForms-htmx: https://github.com/yaal-coop/wtforms-htmx
|
|
102
105
|
|
|
103
106
|
|
|
104
107
|
Links
|
|
@@ -40,6 +40,8 @@ with frameworks even better.
|
|
|
40
40
|
framework, based on the features of Flask-WTF.
|
|
41
41
|
- `Bootstrap-Flask`_ Bootstrap-Flask is a collection of Jinja macros
|
|
42
42
|
for Bootstrap 4 & 5 and Flask using Flask-WTF.
|
|
43
|
+
- `WTForms-htmx`_ Interactive WTForms forms with no hand-written
|
|
44
|
+
JavaScript, powered by htmx and dark magic.
|
|
43
45
|
|
|
44
46
|
.. _Flask-WTF: https://flask-wtf.readthedocs.io/
|
|
45
47
|
.. _WTForms-Alchemy: https://wtforms-alchemy.readthedocs.io/
|
|
@@ -47,6 +49,7 @@ with frameworks even better.
|
|
|
47
49
|
.. _WTForms-Bootstrap5: https://github.com/LaunchPlatform/wtforms-bootstrap5
|
|
48
50
|
.. _Starlette-WTF: https://github.com/muicss/starlette-wtf
|
|
49
51
|
.. _Bootstrap-Flask: https://github.com/helloflask/bootstrap-flask
|
|
52
|
+
.. _WTForms-htmx: https://github.com/yaal-coop/wtforms-htmx
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
Links
|
|
@@ -57,7 +57,6 @@ class FieldList(Field):
|
|
|
57
57
|
self.min_entries = min_entries
|
|
58
58
|
self.max_entries = max_entries
|
|
59
59
|
self.last_index = -1
|
|
60
|
-
self._prefix = kwargs.get("_prefix", "")
|
|
61
60
|
self._separator = separator
|
|
62
61
|
self._field_separator = unbound_field.kwargs.get("separator", "-")
|
|
63
62
|
|
|
@@ -170,17 +169,17 @@ class FieldList(Field):
|
|
|
170
169
|
if index is None:
|
|
171
170
|
index = self.last_index + 1
|
|
172
171
|
self.last_index = index
|
|
173
|
-
name = f"{self.
|
|
172
|
+
name = f"{self.name}{self._separator}{index}"
|
|
174
173
|
id = f"{self.id}{self._separator}{index}"
|
|
175
174
|
options = dict(
|
|
176
175
|
name=name,
|
|
177
|
-
prefix=self._prefix,
|
|
178
176
|
id=id,
|
|
179
177
|
_meta=self.meta,
|
|
180
178
|
translations=self._translations,
|
|
181
179
|
)
|
|
182
180
|
field = self.meta.bind_field(self._form, self.unbound_field, options)
|
|
183
181
|
field.index = index
|
|
182
|
+
field.short_name = str(index)
|
|
184
183
|
field.process(formdata, data)
|
|
185
184
|
self.entries.append(field)
|
|
186
185
|
return field
|
|
@@ -264,6 +264,53 @@ def test_renumbered_entries_in_a_subform_keep_the_subform_prefix():
|
|
|
264
264
|
assert form.sub.a[0].foo.name == "sub-a-0-foo"
|
|
265
265
|
|
|
266
266
|
|
|
267
|
+
@pytest.mark.parametrize("prefix", ["", "p"])
|
|
268
|
+
def test_renumbered_entries_append_to_their_nested_list(prefix):
|
|
269
|
+
"""A list inside a renumbered entry appends entries under the new
|
|
270
|
+
index."""
|
|
271
|
+
|
|
272
|
+
class Component(Form):
|
|
273
|
+
code = StringField()
|
|
274
|
+
|
|
275
|
+
class Block(Form):
|
|
276
|
+
components = FieldList(FormField(Component), min_entries=1)
|
|
277
|
+
|
|
278
|
+
F = make_form(blocks=FieldList(FormField(Block), min_entries=2))
|
|
279
|
+
p = f"{prefix}-" if prefix else ""
|
|
280
|
+
|
|
281
|
+
form = F(DummyPostData({f"{p}blocks-1-components-0-code": "A"}), prefix=prefix)
|
|
282
|
+
appended = form.blocks[0].components.append_entry()
|
|
283
|
+
assert appended.code.name == f"{p}blocks-0-components-1-code"
|
|
284
|
+
|
|
285
|
+
form = F(prefix=prefix)
|
|
286
|
+
form.blocks.pop_entry(0)
|
|
287
|
+
appended = form.blocks[0].components.append_entry()
|
|
288
|
+
assert appended.code.name == f"{p}blocks-0-components-1-code"
|
|
289
|
+
|
|
290
|
+
form = F(prefix=prefix)
|
|
291
|
+
form.blocks.insert_entry(0)
|
|
292
|
+
appended = form.blocks[1].components.append_entry()
|
|
293
|
+
assert appended.code.name == f"{p}blocks-1-components-1-code"
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
@pytest.mark.parametrize("prefix", ["", "p"])
|
|
297
|
+
def test_renumbered_entries_append_to_their_directly_nested_list(prefix):
|
|
298
|
+
"""A list directly inside a renumbered list entry appends entries under
|
|
299
|
+
the new index, at any depth."""
|
|
300
|
+
F = make_form(
|
|
301
|
+
a=FieldList(
|
|
302
|
+
FieldList(FieldList(StringField(), min_entries=1), min_entries=1),
|
|
303
|
+
min_entries=2,
|
|
304
|
+
)
|
|
305
|
+
)
|
|
306
|
+
p = f"{prefix}-" if prefix else ""
|
|
307
|
+
|
|
308
|
+
form = F(prefix=prefix)
|
|
309
|
+
form.a.pop_entry(0)
|
|
310
|
+
assert form.a[0].append_entry()[0].name == f"{p}a-0-1-0"
|
|
311
|
+
assert form.a[0][0].append_entry().name == f"{p}a-0-0-1"
|
|
312
|
+
|
|
313
|
+
|
|
267
314
|
def test_gap_compacted_through_formdata_round_trip():
|
|
268
315
|
"""A formdata with gaps in indices is compacted on read: entries are
|
|
269
316
|
rebuilt with consecutive indices, preserving formdata key order."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|