class ManagePairs(FormView):
form_class = PairsFormSet
model = Pairs
template_name = "pairs.html"
success_url = reverse_lazy("app:template")
def form_valid(self, form):
"""If the form is valid, redirect to the supplied URL."""
form.save()
return super().form_valid(form)
def form_invalid(self, form):
"""If the form is invalid, render the invalid form."""
print(form.errors)
return super().form_invalid(form)
OBSERVATION:
It works for the first few entries (allowing me to add new Pairs … up to a thrid instance). The form starts throwing errors after the second or third instance:
output from form_invalid: [{'id': ['This field is required.'], 'keyword': ['Pair with this Keyword already exists.']}, {'id': ['This field is required.'], 'keyword': ['Pair with this Keyword already exists.']}, {'id': ['This field is required.'], 'keyword': ['Pair with this Keyword already exists.']}, {}, {}]
It appears the formset is attempting to create duplicate instances rather than adding only newer unique instances. Those forms did not change, why is it bothering with them?
You are right. I don’t want to be setting the ids but it appears I have to do so. My options are limited. Everything works when I drop {{ form }} on the template. That approach manages the id nicely. Unfortunately, that approach limits custom styling to some degree. Setting the fields argument doesn’t fix the issue. It does look like I have to manage the ids on the template.
Therefore, given the following id input line (as example) <input type="hidden" name="form-0-id" value="2" id="id_form-0-id">
The index in the above example is “0” while formset.form.id is 2. Do the forms in a formset store their own indexes or do I have to depend on the for-loop counter? If the form objects have index attributes, how do I access them?
{{ form.id }} produces that line. It is not the numeric value for the id as I thought. It is actually input html tag … the whole line that I was looking to reconstruct
The fix:
{% for pairform in form %}
<div class="widgets-tag">
<div class="widgets margin">
<div class="widget widget-text">
<label>Keyword</label>
{{ pairform.keyword }}
</div>
<div class="widget widget-check">
<label>State</label>
{{ pairform.state }}
</div>
<div class="widget widget-check">
<label>Delete</label>
{{ pairform.DELETE }}
</div>
{{ pairform.id }} <!-- the fix here -->
</div>
</div>
{% endfor %}