Reputation: 57198
I don't have an example because I'm not working on anything relevant right now, but am still curious, after reading the docs about formsets:
What is a best practice for having a single view with multiple different model forms that post at the same time (rather 1 combined form, since you can't post multiple forms at the same time, but for lack of a better explanation...), some being single model forms, and others being 1-or-more formsets (e.g. Person
, his 1 Address
, and his 1 or more Pet
objects), like Django does with TabularInline
. Inlines have been in Django for some times, so my suspicion is that there are better practices than what I may find by simply copy/pasting what's in admin/options.py
, no?
Thanks in advance
Upvotes: 0
Views: 144
Reputation: 9428
You should:
Make sure you're using transactions (so, make sure they're turned on, and that you're using something other than MySQL with MyISAM tables). This is true all the time, really, but it's even more true now. :)
Use multiple forms.Form
/forms.ModelForm
objects, which are grouped together in a single HTML <form>
element, such as...
Python:
from django import forms
class FormA(forms.ModelForm):
[...]
class FormB(forms.ModelForm):
[...]
HTML:
<form method="post" action="/path/to/view/">
{% csrf_token %}
{{ form_a }}
{{ form_b }}
<input type="submit" value="Submit Form" />
</form>
Then, when you're processing your forms, simply process them both and make sure that you're requiring both to be valid to actually complete the view in a success case.
from django.db import transaction
from django.http import HttpResponseRedirect
from django.template.response import TemplateResponse
from myapp.forms import FormA, FormB
@transaction.commit_on_success
def present_forms_to_user(request):
if request.method == 'POST':
form_a = FormA(request.POST)
form_b = FormB(request.POST)
if form_a.is_valid() and form_b.is_valid():
# processing code
return HttpResponseRedirect('/path/to/thank/you/page/')
else:
form_a = FormA()
form_b = FormB()
return TemplateResponse(request, 'templates/eggs.html', {
'form_a': form_a,
'form_b': form_b,
})
As a disclaimer, remember that this is a basic example stub, and not meant to be copied blindly. Your ultimate use case for this may be slightly different, and that's fine.
Upvotes: 2