I am trying to find a simple way to create a form that allows the editing of two models with foreign key relationship simultaneously.
After some research, it seems that Inline formsets come very close to what I want to do.
The django documentation offers this example:
from django.db import models
class Author(models.Model):
    name = models.CharField(max_length=100)
class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
And then,
>>> from django.forms import inlineformset_factory
>>> BookFormSet = inlineformset_factory(Author, Book, fields=('title',))
>>> author = Author.objects.get(name='Mike Royko')
>>> formset = BookFormSet(instance=author)
Let’s suppose Author has a second field, city. Can I use the fields argument to add a city to the form?
If inline formsets are not the way to go, is there another way that generates this joint form?
After some more research, I found django model Form. Include fields from related models from 2009 which hints that inline form sets might not be the way to go.
I would be very much interested if there’s a default solution with a different factory.
Advertisement
Answer
Well, this is a bit different from the linked post because there the relationship is a OneToOne and not a ForeignKey.
There is no django factory (at least that I know of) to do what you want automatically. You can try the following instead:
- Create a - ModelFormfor the depended table (- Bookin this case):- class BookForm(forms.ModelForm): class Meta: model = Book fields = ['name', 'city', 'other_field', ...]
- Create an - inline_formsetfor the depended table:- BookFormSet = inlineformset_factory(Author, Book, form=BookForm) 
- Use the formset in your view: - def my_view(request): if request.method == 'POST': formset = BookFormSet(request.POST, instance=request.user) if formset.is_valid(): ... formset.save() else: formset = BookFormSet(instance=request.user) return render_to_response("template.html", {"formset": formset})- OR in a class based view: django class-based views with inline model-form or formset 
- Finally in the template (this part needs a bit of fumbling to get it right, but this is a general idea): - <form action="." method="post"> {% csrf_token %} {{ formset }} {{ formset.management_form }} <input type="submit" value="Submit"> </form>
