问题描述
我最近通过子类化 FormView
来学习Django表单,其中所需的表单分配给 FormView.form_class
属性。当表单验证时,调用 form_valid()
方法(对于那种形式)。例如:from accounts.forms import SignUpForm,UpdateAccountForm,UpdateBillingForm
$但是,我现在有一种情况,一个页面上需要三个唯一的表单(一次只能显示一个用户的窗体)。所以,我想在同一个视图中处理它们。
class SignUpView(FormView) :
form_class = SignUpForm
def form_valid(self,form):
#表单验证时的代码...
是否可以使用FormView进行多表单页面?我不知道如何处理它,无论是将多种形式传递给View(例如其他UpdateAccountForm和UpdateBillingForm),以及区分哪一个被提交/验证?那么最好的方法是什么?
解决方案
1)我在页面上的每个单独的表单中添加了一个隐藏的输入字段(名为action)。例如,这是更新用户信息的形式,这正在拉入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)在我的View逻辑中,我可以通过应用前缀来区分表单和Django )。然后,根据传入的动作,我只将适用的表单绑定到POST请求(因此,所有验证都不会被应用)。在我的情况下,我在form.py,UserForm和BillingForm中定义了两种形式:
from django.views.generic.edit导入查看
从django.shortcuts import render
从django.http import HttpResponse
from accounts.forms import UserForm,BillingForm
class AccountView(View )
def get(self,request):
#GET请求的代码...
def post(self,request):
#instantiate所有唯一的表单(使用前缀)为未绑定
user_form = UserForm(prefix ='user_form')
billing_form = BillingForm(prefix ='billing_form')
#确定哪个表单提交(基于隐藏的输入名为action)
action = self.request.POST ['action']
#绑定到POST并处理正确的表单
if(action =='edit_user'):
user_form = UserForm(request.POST,prefix ='user_form')
如果我们er_form.is_valid():
#用户表单验证,代码离开
elif(action =='edit_billing'):
billing_form = BillingForm(request.POST,prefix ='billing_form')
如果billing_form.is_valid():
#计费表已验证,代码离开
#准备上下文
上下文= {
'user_form':user_form,
'billing_form':billing_form,
}
return render(request,'accounts / account.html',context)
似乎很好,希望这是正确的方法(?)
I've recently learned Django forms by subclassing
FormView
, where the desired form is assigned to theFormView.form_class
attribute. When the form validates, theform_valid()
method is invoked (for that one form). For example:from accounts.forms import SignUpForm, UpdateAccountForm, UpdateBillingForm class SignUpView(FormView): form_class = SignUpForm def form_valid(self, form): # code when form validates...
However, I now have a situation where I need three unique forms on one page (with only one form visible to the user at a time). So, I'd like to handle them all in the same View.
Are multi-form pages possible using FormView? I'm not sure how to handle it, both in terms of passing multiple forms to the View (e.g. the other UpdateAccountForm and UpdateBillingForm), as well as distinguishing which one was submitted/validated? What would be the best way?
解决方案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 (?)
这篇关于Django:使用FormView时可以使用多种形式吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!