简体   繁体   中英

Two django ModelForms on the same page, same model, without Formset

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM