Dear Django group,
after having read all of the Django docs that I could find, I still have two questions
about the proper use of formsets. Summary first:
1. What is a good way to make sure the data received in the POST request agrees with
the "initial" data (number of items and items order is as expected)?
2. What is a good way to augment each form with additional data that is only used for
decoration (rendering additional information) in the template, but is not a form field?
More details:
In a single view, I would like to let the user edit calendar entries, i.e. one CharField
value for each day in a month. The related model is:
from django.db import models
class CalendarEntry(models.Model):
ref_date = models.DateField()
entry = models.CharField(max_length=40, blank=True)
An important issue is that we don't create an instance of CalendarEntry for each day in
a month, but only for those that actually have an entry! However, the formset that is
presented to the user should of course have one "entry" field for each day in the month
(properly initialized if we have a related CalenderEntry instance, blank otherwise).
Thus, it seems that a ModelForm for CalendarEntry cannot be used, because we need some
forms for which a CalendarEntry instance does not exist, but the form instance must
still exist and be initialized with a date (and an empty "entry" field).
Therefore, I made a simple form like this, mimicing the model:
from django import forms
class ExampleForm(forms.Form):
ref_date = forms.DateField(widget=forms.HiddenInput())
entry = forms.CharField(required=False, max_length=40)
The date field is hidden, because the user is not supposed to change it. But we need it
for reference later, when the POST data is processed. (It could possibly be omitted in
this example, but if this was not the days in a month but the students in a class, it
would be the only reliable reference connecting the value to the student.)
Now, let's suppose I came up with a list of initial values, both when the formset is
first created in the GET request, and also later when the data is submitted in the POST
request. For example like this:
# Example is specific to September:
from datetime import date
september_inits = [{"ref_date": date(2015, 9, i + 1)} for i in range(30)]
for ce in CalendarEntry.objects.filter(ref_date__year=2015, ref_date__month=9)
september_inits[ce.ref_date.day-1]["entry"] = ce.entry
Now the view is implemented like this:
from django.forms.formsets import formset_factory
from django.shortcuts import render_to_response
from myapp.forms import ExampleForm
def example_view(request):
september_inits = [...] # as above
ExampleFormSet = formset_factory(ExampleForm)
if request.method == 'POST':
formset = ExampleFormSet(request.POST)
# ~~~~~ Question 1 ~~~~~
# What is the best way (or: a proper way) to check if formset
# agrees to september_inits? Can I use
# formset = ExampleFormSet(request.POST, initial=september_inits)
# then follow
https://docs.djangoproject.com/en/1.8/topics/forms/formsets/#custom-formset-validation ?
# If so, how to access the "initial" data??
if formset.is_valid():
# ...
pass
else:
formset = ExampleFormSet(initial=september_inits)
# ~~~~~ Question 2 ~~~~~
# What is the best way (or: a proper way) to add per-form information,
# e.g. "September 24th is a holiday"?
return render_to_response('manage_articles.html', {'formset': formset})
The two questions have been reformulated as comments above.
Any help would very much be appreciated!
Many thanks and best regards,
Carsten
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/55EDE307.8000704%40cafu.de.
For more options, visit https://groups.google.com/d/optout.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment