I am trying to output two same forms and save them to database with different prefix. I used this post https://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/ as an example. However I get validation error that management form is being tampered with. Could you please kindly advise how to solve it? Thank you.
Also is it possible to filter database by the prefix in this case if i want to retrieve the data later for analysis.
VIEWS.PY
from django.shortcuts import render
from .forms import modelformset_factory, AssumptionsForm
from .models import Assumptions
model_names = ['Form1', 'Form2']
def get_assumptions(request):
AssumptionsFormset = modelformset_factory(
Assumptions, form=AssumptionsForm, extra=5)
if request.method == 'POST':
formsets = [AssumptionsFormset(request.POST, prefix=thing) for thing in model_names]
if all([formset.is_valid() for formset in formsets]):
for formset in formsets:
for form in formset:
form.save()
else:
formsets = [AssumptionsFormset(request.POST, prefix=thing) for thing in model_names]
return render(request, 'assumptions.html', {'formsets': formsets})
ASSUMPTIONS.HTML
<div class="form">
<form action="" method="post">
{% csrf_token %}
{% for formset in formsets %}
{{ formset.management_form }}
{{ formset.non_form_errors.as_ul }}
<h1>{{formset.prefix}}</h1>
<table id="formset" class="form">
{% for form in formset.forms %}
{% if forloop.first %}
<thead><tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr></thead>
{% endif %}
<tr class="{% cycle 'row1' 'row2' %}">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<input type="submit" value="Submit">
{% endfor %}
</form>
</div>
MODELS.PY
from django.db import models
from django.forms import ModelForm
class Assumptions(models.Model):
Worst = models.FloatField(null=True, blank=True, default=None)
Base = models.FloatField(null=True, blank=True, default=None)
Best = models.FloatField(null=True, blank=True, default=None)
FORMS.PY
from django import forms
from django.forms import modelformset_factory, ModelForm
from .models import Assumptions
class AssumptionsForm(ModelForm):
class Meta:
model = Assumptions
fields = '__all__'
You are trying to initialize the formsets with request.POST
on GET
requests, which of course can't work.
Replace the second
formsets = [AssumptionsFormset(request.POST, prefix=thing) for thing in model_names]
with
formsets = [AssumptionsFormset(prefix=thing) for thing in model_names]