我想在网站的索引页面上显示和使用两种表格。
索引页面是一个HomeView,它的上下文包含两种形式 - ContactForm和SubscribtionForm。
我的目标是在单页上使用这两种形式。到目前为止,这是不可能的,因为每次验证失败时,它都会重定向到查看负责表单验证的视图。
索引页面html代码的片段:
<form id="contact-form" class="contact form-horizontal" action="{% url 'contact' %}" method="post" novalidate>
<form id="newsletter-form" class="newsletter_form" action="{% url 'subscribe' %}" method="post" novalidate>
我如何在django中这样做,当我提交它时将使用其他视图来验证和保存数据,但响应将显示在索引页面上?我应该使用javascript / ajax调用来解决这个问题吗?还是有另一种方式?
编辑:
class SubscriberFormView(FormView):
form_class = SubscriberForm
template_name = 'home/subscriber_form.html'
def get_success_url(self):
return reverse('home')
def form_valid(self, form):
form.save()
return redirect(self.get_success_url())
class ContactFormView(FormView):
form_class = ContactForm
template_name = "home/contact_form.html"
def form_valid(self, form):
instance = form.save()
instance.send_confirmation()
instance.send_notification()
return redirect(self.get_success_url())
带前缀的替代解决方案:
class HomeView(FormMixin, TemplateView):
template_name = 'index.html'
form_class = ContactForm
form_class_sub = SubscriberForm
def get_success_url(self):
return reverse('home')
def get_forms(self):
contact_kwargs = self.get_form_kwargs().copy()
contact_kwargs['prefix'] = 'contact'
sub_kwargs = self.get_form_kwargs().copy()
sub_kwargs['prefix'] = 'sub'
return {
'contact_form': self.form_class(**contact_kwargs),
'subscription_form': self.form_class_sub(**sub_kwargs),
}
def post(self, request, *args, **kwargs):
forms = self.get_forms()
if 'contact-submit' in request.POST:
form = forms['contact_form']
form_name = 'contact_form'
elif 'newsletter-submit' in request.POST:
form = forms['subscription_form']
form_name = 'subscription_form'
else:
raise Http404
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form, form_name)
def form_invalid(self, form, form_name):
return self.render_to_response(self.get_context_data())
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if 'contact_form' not in data:
data['contact_form'] = self.get_forms()['contact_form']
if 'subscription_form' not in data:
data['subscription_form'] = self.get_forms()['subscription_form']
return data
def form_valid(self, form):
instance = form.save()
return super().form_valid(form)
基于功能的视图(索引):
def index(request):
contact_form = ContactForm(request.POST or None, prefix='contact')
subscription_form = SubscriberForm(request.POST or None, prefix='sub')
if request.method == "POST":
if 'contact-submit' in request.POST:
form = contact_form
elif 'sub-submit' in request.POST:
form = subscription_form
else:
raise Http404
if form.is_valid():
form.save()
return TemplateResponse(request, template="index.html", context={
'contact_form': contact_form,
'subscription_form': subscription_form,
})
最终版本:
def index(request):
contact_form = ContactForm(None, prefix='contact')
subscription_form = SubscriberForm(None, prefix='sub')
if request.method == "POST":
if 'contact-submit' in request.POST:
contact_form = ContactForm(request.POST, prefix='contact')
if contact_form.is_valid():
contact_form.save()
elif 'sub-submit' in request.POST:
subscription_form = SubscriberForm(request.POST, prefix='sub')
if contact_form.is_valid():
contact_form.save()
else:
raise Http404
return TemplateResponse(request, template="index.html", context={
'contact_form': contact_form,
'subscription_form': subscription_form,
})
答案 0 :(得分:0)
您不应该使用不同的视图来验证数据。表格应在他们已经呈现的同一视图中进行验证。
为了能够在一个视图中使用多个表单,只需使用表单前缀: https://docs.djangoproject.com/en/1.8/ref/forms/api/#prefixes-for-forms