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.
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 ModelForm
for the depended table (Book
in this case):
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ['name', 'city', 'other_field', ...]
Create an inline_formset
for 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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With