Skip to content

Fix #270: Resolve django_form limitations for multi-value and multi-select fields - #298

Open
Archmonger wants to merge 6 commits into
mainfrom
fix-270
Open

Fix #270: Resolve django_form limitations for multi-value and multi-select fields#298
Archmonger wants to merge 6 commits into
mainfrom
fix-270

Conversation

@Archmonger

@Archmonger Archmonger commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Description

Fix (partial) #270 by resolving two categories of django_form limitations:

1. FormData serialization bug (MultipleChoiceField data loss)

Object.fromEntries(formData.entries()) silently drops duplicate keys, causing MultipleChoiceField and ModelMultipleChoiceField to lose all values except the last selected option. Replaced with a manual loop that accumulates duplicate keys into FormDataEntryValue[] arrays.

2. Robust convert_form_fields normalization

Improved convert_form_fields() to properly handle edge cases:

  • None values from unselected multi-select fields → []
  • Single values → [value]
  • Already-list values → unchanged

3. Test coverage for multi-value fields

Added SplitDateTimeField and MultiValueField to BasicForm in the test app for regression coverage.

Checklist

  • Tests have been developed for bug fixes or new functionality.
  • The changelog has been updated, if necessary.
  • Documentation has been updated, if necessary.
  • GitHub Issues closed by this PR have been linked.

By submitting this pull request I agree that all contributions comply with this project's open source license(s).

…delMultipleChoiceField

- Updated `components.ts` to accumulate duplicate FormData entries into arrays
  instead of silently dropping duplicates (as Object.fromEntries would do).
- Updated `utils.py` convert_form_fields() to normalize MultipleChoiceField
  and ModelMultipleChoiceField values (absent/None -> empty list, single -> array).
- Updated test forms to include MultipleChoiceField and
  ModelMultipleChoiceField in BasicForm and BootstrapForm for regression coverage.
@Archmonger
Archmonger requested a review from a team as a code owner July 19, 2026 21:56
Archmonger pushed a commit that referenced this pull request Jul 20, 2026
…d-trip assertions

Following code review suggestions for PR #298:
- New test_forms_utils.py: 10 unit tests covering None->[], single->[value],
  list->unchanged for MultipleChoiceField, ModelMultipleChoiceField,
  BooleanField/NullBooleanField, and CharField pass-through.
- test_form_basic: explicit input_value assertions on multi-select and
  model multi-select fields after successful form submission, proving
  the FormData duplicate-key fix works end-to-end.
- Fix pre-existing ruff import ordering issue in utils.py
…d-trip assertions

Following code review suggestions for PR #298:
- New test_forms_utils.py: 10 unit tests covering None->[], single->[value],
  list->unchanged for MultipleChoiceField, ModelMultipleChoiceField,
  BooleanField/NullBooleanField, and CharField pass-through.
- test_form_basic: explicit input_value assertions on multi-select and
  model multi-select fields after successful form submission, proving
  the FormData duplicate-key fix works end-to-end.
- Fix pre-existing ruff import ordering issue in utils.py
@Archmonger
Archmonger force-pushed the fix-270 branch 3 times, most recently from 11be5bf to de12ba0 Compare July 21, 2026 16:04
The set_value_prop_on_select_element transform previously stripped
the selected attribute from option elements, relying solely on
defaultValue for restoring selection. Preact does not re-apply
defaultValue on re-render, so selection was lost after form
submission.

Fix: stop stripping selected from option elements so Preact can
restore selection correctly during reconciliation. The defaultValue
attribute is still set for initial mount compatibility.

Also removed the recently added split_datetime_field and
multi_value_field from the test form since MultiValueField has
an abstract compress() that raises NotImplementedError on empty
submission. Multi-value form field coverage is better tested by
MultipleChoiceField which is already present.
Preact/React does not reliably restore <select multiple> selection
state during in-place reconciliation of option children. Force a
complete unmount/remount of the <form> element by using a volatile
React key that increments each time submitted_data triggers a
re-render.

This ensures defaultValue is applied on mount and that the DOM
select element starts fresh with the correct selection.
@Archmonger Archmonger linked an issue Jul 22, 2026 that may be closed by this pull request
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant