[Django]-Django formset_factory vs modelformset_factory vs inlineformset_factory

36👍

The difference between the 3 formset factories is basically:

  • formset_factory lets you render a bunch of forms together, but these forms are NOT necessarily related to a particular database models (this is not what you need, since you have models for everything)
  • modelformset_factory lets you create/edit a bunch of Django model objects together, for example, if you were managing the "menu" you could use a modelformset_factory(Dish, fields=('name'))
  • inlineformset_factory lets you manage a bunch of Django model objects that are all related to a single instance of another model. For example, if you wanted to manage all of the MealPhotos that were taken at a particular Meal, this is what you would use

To answer your specific scenarios:

If you wanted a page that created a single Meal and a single Reservation at the same time, without assigning any Dishes yet, you don’t need any formsets. You could just use a ModelForm for Meal and a ModelForm for Reservation.

Later on, if you want to attach multiple Dishes to the Meal, you would use an inlineformset_factory(Meal, Dish) to edit multiple Dishes belonging to a single Meal

Since we are using an inlineformset_factory, we have to create the Meal instance in the view that renders the form. Something like this:

DishFormSet = inlineformset_factory(Meal, Dish)
bday_dinner = Meal.objects.create(name='30th Birthday dinner')
formset = DishFormSet(instance=bday_dinner)

For someone uploading photos of the Meal, you would use:

PhotosFormSet = inlineformset_factory(Meal, MealPhotos)
bday_dinner = Meal.objects.get(name='30th Birthday dinner')
formset = PhotosFormSet(instance=bday_dinner)

This tells Django that all the photos submitted are all linked to that one Meal, but allows the possibility of assigning each photo to a different Dish (via a dropdown in the form).

Note: In the first scenario, I haven’t tested whether you the use of a ManyToManyField as Meal.dishes is supported by the formset factory. If it isn’t, then you could simply use a ModelFormset(Dish) and after those are created, link them to the Meal in the Django view that process the form submission.

Leave a comment