27š
Well, for what itās worth hereās what ultimately worked for me, using a generic View.
1) I added a hidden input field (named āactionā) to each individual form on the page. For example, this is the form for updating userās info, which is pulling in UserForm:
<form action='/account/' method='post'>{% csrf_token %}
<input type='hidden' name='action' value='edit_user'>
{{ user_form.as_p }}
<input type='submit' value='Update'>
</form>
2) In my View logic, I can distinguish the forms by applying a prefix (per other SO posts and Django docs). Then, depending on the incoming āactionā, I only bind the applicable form to the POST request (so validations arenāt applied across all of them). In my case, I had two forms defined in forms.py, UserForm and BillingForm:
from django.views.generic.edit import View
from django.shortcuts import render
from django.http import HttpResponse
from accounts.forms import UserForm, BillingForm
class AccountView(View):
def get(self, request):
# code for GET request...
def post(self, request):
#instantiate all unique forms (using prefix) as unbound
user_form = UserForm(prefix='user_form')
billing_form = BillingForm(prefix='billing_form')
# determine which form is submitting (based on hidden input called 'action')
action = self.request.POST['action']
# bind to POST and process the correct form
if (action == 'edit_user'):
user_form = UserForm(request.POST, prefix='user_form')
if user_form.is_valid():
# user form validated, code away..
elif (action == 'edit_billing'):
billing_form = BillingForm(request.POST, prefix='billing_form')
if billing_form.is_valid():
# billing form validated, code away..
# prep context
context = {
'user_form': user_form,
'billing_form': billing_form,
}
return render(request, 'accounts/account.html', context)
Seems to work well, hopefully this is the right approach (?)
1š
You can write a plain python class mimicking the Form
API (at least the useful parts) and wrapping your three forms. Detecting which form has been submitted is just a matter of adding a hidden input with the formās identifier in each form (hint : use prefixes for your forms and use that same prefix as identifier).
The other solution is to use a simple function-based view instead, but even there Iād still use the same āform wrapperā pattern as far as Iām concerned.
- [Django]-DRF: custom ordering on related serializers
- [Django]-Django FileField upload is not working for me
- [Django]-Django Background Task