Reputation: 17894
I have a form that allow users to log their activities. To make it simple, let's say I only have two fields that I want a user to fill out.
During a day, a user can fill out multiple time + action pairs. I used javascript on the front end to allow users to add these pairs as they wish.
Thus, I do not know how many pairs there will be beforehand. And thus, I cannot create a predefined ModelForm for it.
To deal with this issue, I labeled each Time and Action field with a unique name. So when I receive a POST request, I geta list like this inside the request.POST dictionary:
Then, I subtract each pair out of the dictionary and put them into a ModelForm for validation and save to the database.
class TimeActionModel(Model):
time = DateField()
action = CharField(max_length=100)
class TimeActionForm(ModelForm):
class Meta:
model = TimeActionModel
class TimeActionView(View):
def post(self, request, *args, **kwargs):
self._subtract_and_save(request)
def _subtract_and_save(request):
#loop through the request.POST dictionary
#pull out each pair
#stuff each one into a ModelForm object
if form.is_valid():
form.save()
Here is my quesiton:
Thank you!
Upvotes: 4
Views: 170
Reputation: 19902
There is a concept in Django called formset:
A formset is a layer of abstraction to work with multiple forms on the same page. It can be best compared to a data grid.
The Django way would be to use Model formsets:
Like regular formsets, Django provides a couple of enhanced formset classes that make it easy to work with Django models.
Therefore you could create a model formset for your TimeActionModel
as such:
from django.forms.models import modelformset_factory
TimeActionFormset = modelformset_factory(TimeActionModel)
You can read more on that in the documentation. It has extensive use cases and examples to cover your case.
UPDATE: The extras
parameter of the formset is not quite important. You can easily manipulate the number of extra forms in your formset with a bit of javascript. There are also contrib packages for that such as django-dynamic-formset.
UPDATE2: The name of the fields depends on the prefix
used too, which I recommend it in case of many different forms/formsets in a single page, but you can easily deduce it looking at a default form that Django renders.
Also please take not not to forget in your template to include {{ my_formset.management_form }}
and {{ my_formsets_form.id }}
!
Upvotes: 4