Skip to content

Commit 332f70c

Browse files
committed
fix form element names of nested embedded model fields
1 parent 373a60b commit 332f70c

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

django_mongodb_backend/forms/fields/embedded_model.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,17 @@ def decompress(self, value):
2020

2121

2222
class EmbeddedModelBoundField(forms.BoundField):
23+
def __init__(self, form, field, name, prefix_override=None):
24+
super().__init__(form, field, name)
25+
# prefix_override overrides the prefix in self.field.form_kwargs so
26+
# that nested embedded model form elements have the correct name.
27+
self.prefix_override = prefix_override
28+
2329
def __str__(self):
2430
"""Render the model form as the representation for this field."""
2531
form = self.field.model_form_cls(instance=self.value(), **self.field.form_kwargs)
32+
if self.prefix_override:
33+
form.prefix = self.prefix_override
2634
return mark_safe(f"{form.as_div()}") # noqa: S308
2735

2836

@@ -53,7 +61,9 @@ def compress(self, data_dict):
5361
return self.model_form._meta.model(**values)
5462

5563
def get_bound_field(self, form, field_name):
56-
return EmbeddedModelBoundField(form, self, field_name)
64+
# Nested embedded model form fields need a double prefix.
65+
prefix_override = f"{form.prefix}-{self.model_form.prefix}" if form.prefix else None
66+
return EmbeddedModelBoundField(form, self, field_name, prefix_override)
5767

5868
def bound_data(self, data, initial):
5969
if self.disabled:

tests/model_forms_/test_embedded_model.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,40 @@ def test_all_missing_data(self):
216216
form = BookForm(data, instance=book)
217217
self.assertFalse(form.is_valid())
218218
self.assertEqual(form.errors["publisher"], ["This field is required."])
219+
220+
def test_rendering(self):
221+
form = BookForm()
222+
self.assertHTMLEqual(
223+
str(form.fields["publisher"].get_bound_field(form, "publisher")),
224+
"""
225+
<div>
226+
<label for="id_publisher-name">Name:</label>
227+
<input type="text" name="publisher-name" maxlength="50"
228+
required id="id_publisher-name">
229+
</div>
230+
<div>
231+
<fieldset>
232+
<legend>Address:</legend>
233+
<div>
234+
<label for="id_publisher-address-po_box">PO Box:</label>
235+
<input type="text" name="publisher-address-po_box" maxlength="50"
236+
id="id_publisher-address-po_box">
237+
</div>
238+
<div>
239+
<label for="id_publisher-address-city">City:</label>
240+
<input type="text" name="publisher-address-city" maxlength="20"
241+
required id="id_publisher-address-city">
242+
</div>
243+
<div>
244+
<label for="id_publisher-address-state">State:</label>
245+
<input type="text" name="publisher-address-state" maxlength="2"
246+
required id="id_publisher-address-state">
247+
</div>
248+
<div>
249+
<label for="id_publisher-address-zip_code">Zip code:</label>
250+
<input type="number" name="publisher-address-zip_code"
251+
required id="id_publisher-address-zip_code">
252+
</div>
253+
</fieldset>
254+
</div>""",
255+
)

0 commit comments

Comments
 (0)