如果我有两种形式:
class ContactForm(forms.Form): name = forms.CharField() message = forms.CharField(widget=forms.Textarea) class SocialForm(forms.Form): name = forms.CharField() message = forms.CharField(widget=forms.Textarea)
并想使用基于类的视图,并将两种形式都发送到模板,那有可能吗?
class TestView(FormView): template_name = 'contact.html' form_class = ContactForm
看来FormView一次只能接受一种形式。尽管在基于函数的视图中,我可以轻松地将两个表单发送到模板,然后在request.POST中检索这两个表单的内容。
variables = {'contact_form':contact_form, 'social_form':social_form } return render(request, 'discussion.html', variables)
这是使用基于类的视图(通用视图)的限制吗?
默认情况下,基于类的视图每个视图仅支持一个表单。但是还有其他方法可以满足您的需求。但是同样,这不能同时处理两种形式。这也适用于大多数基于类的视图以及常规形式。
views.py
class MyClassView(UpdateView):
template_name = 'page.html' form_class = myform1 second_form_class = myform2 success_url = '/' def get_context_data(self, **kwargs): context = super(MyClassView, self).get_context_data(**kwargs) if 'form' not in context: context['form'] = self.form_class(request=self.request) if 'form2' not in context: context['form2'] = self.second_form_class(request=self.request) return context def get_object(self): return get_object_or_404(Model, pk=self.request.session['value_here']) def form_invalid(self, **kwargs): return self.render_to_response(self.get_context_data(**kwargs)) def post(self, request, *args, **kwargs): self.object = self.get_object() if 'form' in request.POST: form_class = self.get_form_class() form_name = 'form' else: form_class = self.second_form_class form_name = 'form2' form = self.get_form(form_class) if form.is_valid(): return self.form_valid(form) else: return self.form_invalid(**{form_name: form})
模板
这是一个示例用法
class SignupLoginView(MultiFormsView): template_name = 'public/my_login_signup_template.html' form_classes = {'login': LoginForm, 'signup': SignupForm} success_url = 'my/success/url' def get_login_initial(self): return {'email':'dave@dave.com'} def get_signup_initial(self): return {'email':'dave@dave.com'} def get_context_data(self, **kwargs): context = super(SignupLoginView, self).get_context_data(**kwargs) context.update({"some_context_value": 'blah blah blah', "some_other_context_value": 'blah'}) return context def login_form_valid(self, form): return form.login(self.request, redirect_url=self.get_success_url()) def signup_form_valid(self, form): user = form.save(self.request) return form.signup(self.request, user, self.get_success_url())
模板看起来像这样
<form class="login" method="POST" action="{% url 'my_view' %}"> {% csrf_token %} {{ forms.login.as_p }} <button name='action' value='login' type="submit">Sign in</button> </form> <form class="signup" method="POST" action="{% url 'my_view' %}"> {% csrf_token %} {{ forms.signup.as_p }} <button name='action' value='signup' type="submit">Sign up</button> </form>
模板上要注意的重要事项是提交按钮。他们必须将其“名称”属性设置为“动作”,并且其“值”属性必须与“ form_classes”字典中为表单指定的名称相匹配。这用于确定已提交的单个表格。