How to Use Inline Formset in Django: Simple Guide
Use Django's
inlineformset_factory to create a formset for related models, linking child objects to a parent model. This allows editing multiple related objects in one form by specifying the parent model, child model, and form class.Syntax
The inlineformset_factory function creates a formset class for editing related objects inline. It requires these main parts:
- parent_model: The main model class (e.g., a blog post).
- model: The related child model (e.g., comments on the post).
- form (optional): A custom form class for the child model.
- extra (optional): Number of extra empty forms to show.
- can_delete (optional): Allow deleting child objects.
This formset lets you edit multiple child objects linked to one parent in a single form.
python
from django.forms import inlineformset_factory CommentFormSet = inlineformset_factory( parent_model=Post, model=Comment, form=CommentForm, extra=2, can_delete=True )
Example
This example shows how to use an inline formset to edit comments related to a blog post in a Django view and template.
python
from django.shortcuts import render, get_object_or_404, redirect from django.forms import inlineformset_factory from .models import Post, Comment from .forms import CommentForm def edit_post_comments(request, post_id): post = get_object_or_404(Post, id=post_id) CommentFormSet = inlineformset_factory(Post, Comment, form=CommentForm, extra=1, can_delete=True) if request.method == 'POST': formset = CommentFormSet(request.POST, instance=post) if formset.is_valid(): formset.save() return redirect('post_detail', post_id=post.id) else: formset = CommentFormSet(instance=post) return render(request, 'edit_comments.html', {'formset': formset, 'post': post})
Output
Renders a form with existing comments for the post and one extra empty form to add a new comment. On submit, saves all changes and redirects.
Common Pitfalls
- Not passing
instance=parent_objectto the formset causes errors or no data binding. - Forgetting to call
formset.is_valid()before saving leads to exceptions. - Not including management form in the template causes validation errors.
- Using
extra=0without existing related objects shows no forms.
Always include {{ formset.management_form }} in your template inside the <form> tag.
python
Wrong:
formset = CommentFormSet(request.POST) # Missing instance
Right:
formset = CommentFormSet(request.POST, instance=post)Quick Reference
| Parameter | Description |
|---|---|
| parent_model | The main model class to which child objects relate |
| model | The child model to edit inline |
| form | Optional custom form class for child model |
| extra | Number of extra empty forms to display (default 3) |
| can_delete | Allow deleting child objects via formset (default False) |
Key Takeaways
Use inlineformset_factory to link child forms to a parent model instance.
Always pass the parent instance to the formset with the instance parameter.
Include the management form in your template to avoid validation errors.
Call is_valid() before saving the formset to ensure data integrity.
Set extra to control how many empty forms appear for new child objects.