Django在单页/ url下有两个单独的表单

时间:2015-11-15 09:30:45

标签: django forms

我想在网站的索引页面上显示和使用两种表格。

索引页面是一个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,
    })

1 个答案:

答案 0 :(得分:0)

您不应该使用不同的视图来验证数据。表格应在他们已经呈现的同一视图中进行验证。

为了能够在一个视图中使用多个表单,只需使用表单前缀: https://docs.djangoproject.com/en/1.8/ref/forms/api/#prefixes-for-forms