Django: Multiple forms possible when using FormView?

后端 未结 2 1812
天涯浪人
天涯浪人 2020-12-24 15:17

I\'ve recently learned Django forms by subclassing FormView, where the desired form is assigned to the FormView.form_class attribute. When the form

相关标签:
2条回答
  • 2020-12-24 15:47

    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 (?)

    0 讨论(0)
  • 2020-12-24 15:51

    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.

    0 讨论(0)
提交回复
热议问题