Reputation: 4937
I have two model forms on the same page. The form only has a single field, event
that is selected:
forms.py
class RegistrationForm(forms.ModelForm):
class Meta:
model = Registration
fields = ['event']
views.py
form1 = RegistrationForm(request.POST or None, instance=user_reg1)
form2 = RegistrationForm(request.POST or None, instance=user_reg2)
if request.method == 'POST':
if form1.is_valid() and form2.is_valid():
form1.save()
form2.save()
.html
<form method="POST" action=""> {% csrf_token %}
{{ form1 }}
{{ form2 }}
<input type="submit" value="Save Selections"/>
</form>
The forms display and populates properly, but when I change the values and hit the save button, it always saves the form2 selection to both instances.
I've noticed that the DOM ids are the same, and I've been able to change the DOM id by grabbing a unique field in the Registration model (in this case, block
)
form.py
class RegistrationForm(forms.ModelForm):
class Meta:
model = Registration
fields = ['event']
def __init__(self, *args, **kwargs):
block = kwargs.pop('block') # a unique field in the Registration model
super(RegistrationForm, self).__init__(*args, **kwargs)
if block:
DOM_id = "event-" + str(block)
self.fields['event'].widget.attrs.update({'id': DOM_id, })
This is giving the field a unique id, but both forms are still encompassed by a div with the same id: div_id_event
rendered html
<form method="POST" action=""> <input type='hidden' name='csrfmiddlewaretoken' value='...' />
<div id="div_id_event" class="form-group">
<label for="event-Flex-1" class="control-label requiredField">Event<span class="asteriskField">*</span> </label>
<div class="controls ">
<select class="select form-control" id="event-Flex-1" name="event" required>
<option value="">---------</option>
<option value="10">stuff</option>
...
</select>
</div>
</div>
<div id="div_id_event" class="form-group">
<label for="event-Flex-2" class="control-label requiredField">
Event<span class="asteriskField">*</span> </label>
<div class="controls ">
<select class="select form-control" id="event-Flex-2" name="event" required>
<option value="">---------</option>
<option value="10">stuff</option>
....
</select>
</div>
</div>
<input type="submit" value="Save Selections"/>
</form>
I don't even know if the id matters. Is there a way for me to get these two forms to cooperate without using a Formset?
Upvotes: 0
Views: 755
Reputation: 3223
The id of the DOM element is not important in this case. The important property is the name
of the input element.
It sounds like you need to use the prefix
attribute of the ModelForm. Check https://docs.djangoproject.com/en/2.0/ref/forms/api/#prefixes-for-forms.
Initialise the form with
form1 = RegistrationForm(request.POST or None, instance=user_reg1, prefix='user1')
form2 = RegistrationForm(request.POST or None, instance=user_reg2, prefix='user2')
You'll then end up with input element names prefixed with the value you gave for the prefix argument, which will prevent the namespace collision you are experiencing.
Upvotes: 1