I need to display one form, with multiple fields from 2 different models. Form will contain only part of fields from models, and layout will be made using the crispy forms.
My models:
class Company(BaseModel):
title = models.CharField(_('Company'), max_length=128)
domain = models.CharField(_('Domain'), max_length=128)
class Account(BaseModel):
company = models.ForeignKey(Company)
user = models.OneToOneField(User)
role = models.CharField(_('Role'), choices=ROLES, default='member', max_length=32)
Fields which I want to show in form: company title, user first name, user last name, user email
Is it even possible? How can I do this?
The other answers on this page involve tossing away the benefits of model forms and possibly needing to duplicate some of the functionality you get for free.
The real key is to remember that one html form != one django form. You can have multiple forms wrapped in a single html form tag.
So you can just create two model forms and render them both in your template. Django will handle working out which POST parameters belong to each unless some field names clash - in which case give each form a unique prefix when you instantiate it.
Forms:
class CompanyForm(forms.ModelForm):
class Meta:
fields = [...]
model = Company
class AccountForm(forms.ModelForm):
class Meta:
fields = [...]
model = Account
View:
if request.method == 'POST':
company_form = CompanyForm(request.POST)
account_form = AccountForm(request.POST)
if company_form.is_valid() and account_form.is_valid():
company_form.save()
account_form.save()
return HttpResponseRedirect('/success')
else:
context = {
'company_form': company_form,
'account_form': account_form,
}
else:
context = {
'company_form': CompanyForm(),
'account_form': AccountForm(),
}
return TemplateResponse(request, 'your_template.html', context)
Template:
<form action="." method="POST">
{% csrf_token %}
{{ company_form.as_p }}
{{ account_form.as_p }}
<button type="submit">
</form>