Formsets & Inline Formsets
Formsets manage multiple forms on the same page — like editing several items at once. Inline formsets handle related objects (e.g., editing a post and its images together). They are powerful for admin-like editing interfaces.
20 min•By Priygop Team•Updated 2026
Formset Types
- formset_factory(Form, extra=N) — Multiple copies of same form
- modelformset_factory(Model, fields) — Multiple model instances
- inlineformset_factory(Parent, Child) — Related model editing
- extra=N — Number of blank forms to display
- can_delete=True — Allow removing existing instances
- formset.is_valid() — Validates all forms
- formset.save() — Saves all valid forms
Formset Example
Formset Example
# blog/forms.py
# from django.forms import inlineformset_factory, modelformset_factory
# Inline formset — Edit post images together with post
# ImageFormSet = inlineformset_factory(
# Post, # Parent model
# PostImage, # Child model
# fields=['image', 'caption'],
# extra=3, # 3 blank image forms
# can_delete=True, # Allow removing images
# )
# blog/views.py
# def edit_post_with_images(request, pk):
# post = get_object_or_404(Post, pk=pk)
# if request.method == 'POST':
# form = PostForm(request.POST, instance=post)
# formset = ImageFormSet(
# request.POST, request.FILES,
# instance=post
# )
# if form.is_valid() and formset.is_valid():
# form.save()
# formset.save()
# messages.success(request, 'Post updated!')
# return redirect('blog:detail', pk=post.pk)
# else:
# form = PostForm(instance=post)
# formset = ImageFormSet(instance=post)
#
# return render(request, 'blog/edit_with_images.html', {
# 'form': form,
# 'formset': formset,
# })
# Template
# <form method="post" enctype="multipart/form-data">
# {% csrf_token %}
# {{ form.as_p }}
# <h3>Images</h3>
# {{ formset.management_form }}
# {% for image_form in formset %}
# {{ image_form.as_p }}
# {% endfor %}
# <button type="submit">Save</button>
# </form>Tip
Tip
Combine multiple mixins for complex views. Order matters — put LoginRequiredMixin first for proper method resolution.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Not restricting object access. Always check permissions in get_object() or dispatch() to prevent unauthorized access.
Practice Task
Note
(1) Create a custom mixin for ownership checks. (2) Apply it to UpdateView and DeleteView. (3) Test access control.
Quick Quiz
Key Takeaways
- Formsets manage multiple forms on the same page — like editing several items at once.
- formset_factory(Form, extra=N) — Multiple copies of same form
- modelformset_factory(Model, fields) — Multiple model instances
- inlineformset_factory(Parent, Child) — Related model editing