Skip to content

Commit 67b5bf7

Browse files
committed
add support for nested forms
1 parent 825ffca commit 67b5bf7

File tree

4 files changed

+790
-7
lines changed

4 files changed

+790
-7
lines changed

django_mongodb_backend/forms/fields/embedded_model_array.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def __init__(self, model, *, prefix, max_num=None, extra_forms=3, **kwargs):
2222
def clean(self, value):
2323
if not value:
2424
return []
25-
formset = self.formset(value, prefix=self.prefix)
25+
formset = self.formset(value, prefix=self.prefix_override or self.prefix)
2626
if not formset.is_valid():
2727
raise ValidationError(formset.errors + formset.non_form_errors())
2828
cleaned_data = []
@@ -39,16 +39,18 @@ def has_changed(self, initial, data):
3939
return formset.has_changed()
4040

4141
def get_bound_field(self, form, field_name):
42-
return EmbeddedModelArrayBoundField(form, self, field_name)
42+
# Nested embedded model form fields need a double prefix.
43+
self.prefix_override = f"{form.prefix}-{self.prefix}" if form.prefix else None
44+
return EmbeddedModelArrayBoundField(form, self, field_name, self.prefix_override)
4345

4446

4547
class EmbeddedModelArrayBoundField(forms.BoundField):
46-
def __init__(self, form, field, name):
48+
def __init__(self, form, field, name, prefix_override):
4749
super().__init__(form, field, name)
4850
self.formset = field.formset(
4951
self.data if form.is_bound else None,
5052
initial=models_to_dicts(self.initial),
51-
prefix=self.html_name,
53+
prefix=prefix_override if prefix_override else self.html_name,
5254
)
5355

5456
def __str__(self):

tests/model_forms_/forms.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django import forms
22

3-
from .models import Author, Book, Movie
3+
from .models import Author, Book, Movie, Store
44

55

66
class AuthorForm(forms.ModelForm):
@@ -19,3 +19,9 @@ class MovieForm(forms.ModelForm):
1919
class Meta:
2020
fields = "__all__"
2121
model = Movie
22+
23+
24+
class StoreForm(forms.ModelForm):
25+
class Meta:
26+
fields = "__all__"
27+
model = Store

tests/model_forms_/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,13 @@ class Movie(models.Model):
4444

4545
def __str__(self):
4646
return self.title
47+
48+
49+
class Product(EmbeddedModel):
50+
name = models.CharField(max_length=255)
51+
reviews = EmbeddedModelArrayField(Review)
52+
53+
54+
class Store(models.Model):
55+
name = models.CharField(max_length=255)
56+
products = EmbeddedModelArrayField(Product)

0 commit comments

Comments
 (0)