I have been following this useful-looking article http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/. Unfortunately he doesn’t hint at the template code, so I’m guessing there.
I want to create a bunch of forms in a page, to add multiple objects to a model, with some common properties set by another form either in the page’s variables or at the top of the page. This is for a teacher’s marksheet.
My views.py:
def record_assessments(request, teachinggroup, objective):
theclass = TeachingGroup.objects.get(name__iexact = teachinggroup)
pupils = Pupil.objects.filter(teaching_group = theclass)
theobjective = Objective.objects.get(code = objective)
thedate = datetime.date.today()
if request.method == 'POST':
aforms = [PupilAssessmentForm(request.POST, prefix=x.id, instance=Assessment()) for x in pupils]
if all(af.is_valid() for af in aforms):
for af in aforms:
new_record = af.save(commit = False)
new_record.objective = theobjective
new_record.date = thedate
new_record.save()
return redirect("/app/" + theclass + "/" + marksheet + "/" + theobjective.strand.code|lower + "/")
else:
aforms = [PupilAssessmentForm(prefix=str(x.id)) for x in pupils]
return render_to_response('recordassessments.html', locals())
I haven’t managed to check the logic in the first if loop yet, as I haven’t managed to POST the form properly yet.
The page renders properly if I put
else:
aforms = [PupilAssessmentForm(prefix=str(x.id), instance=x) for x in pupils]
But then I’m tying a ModelForm from the Assessment model to an object in the Pupil model, which seems wrong.
My template:
{% for af in aforms %}
<form action="" method="post">
{{af.instance}}{{ af.errors }}
<p>
{{ af }}
{% endfor %}
<input type="submit" value="Submit">
</form>
The error (selected snippets):
Exception Type: TemplateSyntaxError
Exception Value: Caught DoesNotExist while rendering:
error at line 20
Caught DoesNotExist while rendering:
20 {% for af in aforms %}
And yet the aforms list appears in the page variables:
aforms
[<two.app.forms.PupilAssessmentForm object at 0x21db0d0>,
<two.app.forms.PupilAssessmentForm object at 0x21db650>]
I’m not sure why, but I managed to do it by changing the list to a dictionary, which suited my needs anyway for displaying the form as a table row per pupil together with some other assessment data. My original question remains open for anyone who knows an alternative method that more directly addresses the question I was originally asking, but here’s how I did it:
views.py (the relevant bits):
I’m not sure whether there’s a more elegant way to assemble the dictionary, as mine isn’t particularly DRY. And I have no idea why I could unpack a dictionary containing a form yet not a list. Was my syntax wrong? Anyway: problem sorted; page renders.