如何构建多个提交按钮django表单?

时间:2023-01-16 19:19:19

I have form with one input for email and two submit buttons to subscribe and unsubscribe from newsletter:

我有一个电子邮件输入和两个提交按钮,以订阅和退订通讯:

<form action="" method="post">
{{ form_newsletter }}
<input type="submit" name="newsletter_sub" value="Subscribe" />
<input type="submit" name="newsletter_unsub" value="Unsubscribe" />
</form>

I have also class form:

我还有课表:

class NewsletterForm(forms.ModelForm):
    class Meta:
        model = Newsletter
        fields = ('email',)

I must write my own clean_email method and I need to know by which button was form submited. But the value of submit buttons aren't in self.cleaned_data dictionary. Could I get values of buttons otherwise?

我必须编写我自己的clean_email方法,并且我需要知道是通过哪个按钮提交表单的。但是提交按钮的值并不在self中。cleaned_data字典。我可以得到按钮的值吗?

5 个解决方案

#1


74  

You can use self.data in the clean_email method to access the POST data before validation. It should contain a key called newsletter_sub or newsletter_unsub depending on which button was pressed.

您可以使用自我。在验证之前,使用clean_email方法中的数据访问POST数据。它应该包含一个名为newsletter或newsletter unsub的键,这取决于按哪个键。

# in the context of a django.forms form

def clean(self):
    if 'newsletter_sub' in self.data:
        # do subscribe
    elif 'newsletter_unsub' in self.data:
        # do unsubscribe

#2


194  

Eg:

例如:

if 'newsletter_sub' in request.POST:
    # do subscribe
elif 'newsletter_unsub' in request.POST:
    # do unsubscribe

#3


9  

You can also do like this,

你也可以这样做,

 <form method='POST'>
    {{form1.as_p}}
    <button type="submit" name="btnform1">Save Changes</button>
    </form>
    <form method='POST'>
    {{form2.as_p}}
    <button type="submit" name="btnform2">Save Changes</button>
    </form>

CODE

代码

if request.method=='POST' and 'btnform1' in request.POST:
    do something...
if request.method=='POST' and 'btnform2' in request.POST:
    do something...

#4


3  

It's an old question now, nevertheless I had the same issue and found a solution that works for me: I wrote MultiRedirectMixin.

这是一个古老的问题,尽管我有同样的问题,并且找到了一个适合我的解决方案:我写了MultiRedirectMixin。

from django.http import HttpResponseRedirect

class MultiRedirectMixin(object):
    """
    A mixin that supports submit-specific success redirection.
     Either specify one success_url, or provide dict with names of 
     submit actions given in template as keys
     Example: 
       In template:
         <input type="submit" name="create_new" value="Create"/>
         <input type="submit" name="delete" value="Delete"/>
       View:
         MyMultiSubmitView(MultiRedirectMixin, forms.FormView):
             success_urls = {"create_new": reverse_lazy('create'),
                               "delete": reverse_lazy('delete')}
    """
    success_urls = {}  

    def form_valid(self, form):
        """ Form is valid: Pick the url and redirect.
        """

        for name in self.success_urls:
            if name in form.data:
                self.success_url = self.success_urls[name]
                break

        return HttpResponseRedirect(self.get_success_url())

    def get_success_url(self):
        """
        Returns the supplied success URL.
        """
        if self.success_url:
            # Forcing possible reverse_lazy evaluation
            url = force_text(self.success_url)
        else:
            raise ImproperlyConfigured(
                _("No URL to redirect to. Provide a success_url."))
        return url

#5


0  

one url to the same view! like so!

同一个视图的一个url !像这样!

###urls.py###
url(r'^$', views.landing.as_view(), name = 'landing'),

####views.py####
class landing(View):
    template_name = '/home.html'
    form_class1 = forms.pynamehere1
    form_class2 = forms.pynamehere2
        def get(self, request):
            form1 = self.form_class1(None)
            form2 = self.form_class2(None)
            return render(request, self.template_name, { 'register':form1, 'login':form2,})

         def post(self, request):
             if request.method=='POST' and 'htmlsubmitbutton1' in request.POST:
                    ## do what ever you want to do for first function ####
             if request.method=='POST' and 'htmlsubmitbutton2' in request.POST:
                     ## do what ever you want to do for second function ####
                    ## return def post###  
             return render(request, self.template_name, {'form':form,})


####/home.html####
#### form 1 ####
<form action="" method="POST" >
  {% csrf_token %}
  {{ register.as_p }}
<button type="submit" name="htmlsubmitbutton1">Login</button>
</form>
#### form 2 ####
<form action="" method="POST" >
  {% csrf_token %}
  {{ login.as_p }}
<button type="submit" name="htmlsubmitbutton2">Login</button>
</form>

#1


74  

You can use self.data in the clean_email method to access the POST data before validation. It should contain a key called newsletter_sub or newsletter_unsub depending on which button was pressed.

您可以使用自我。在验证之前,使用clean_email方法中的数据访问POST数据。它应该包含一个名为newsletter或newsletter unsub的键,这取决于按哪个键。

# in the context of a django.forms form

def clean(self):
    if 'newsletter_sub' in self.data:
        # do subscribe
    elif 'newsletter_unsub' in self.data:
        # do unsubscribe

#2


194  

Eg:

例如:

if 'newsletter_sub' in request.POST:
    # do subscribe
elif 'newsletter_unsub' in request.POST:
    # do unsubscribe

#3


9  

You can also do like this,

你也可以这样做,

 <form method='POST'>
    {{form1.as_p}}
    <button type="submit" name="btnform1">Save Changes</button>
    </form>
    <form method='POST'>
    {{form2.as_p}}
    <button type="submit" name="btnform2">Save Changes</button>
    </form>

CODE

代码

if request.method=='POST' and 'btnform1' in request.POST:
    do something...
if request.method=='POST' and 'btnform2' in request.POST:
    do something...

#4


3  

It's an old question now, nevertheless I had the same issue and found a solution that works for me: I wrote MultiRedirectMixin.

这是一个古老的问题,尽管我有同样的问题,并且找到了一个适合我的解决方案:我写了MultiRedirectMixin。

from django.http import HttpResponseRedirect

class MultiRedirectMixin(object):
    """
    A mixin that supports submit-specific success redirection.
     Either specify one success_url, or provide dict with names of 
     submit actions given in template as keys
     Example: 
       In template:
         <input type="submit" name="create_new" value="Create"/>
         <input type="submit" name="delete" value="Delete"/>
       View:
         MyMultiSubmitView(MultiRedirectMixin, forms.FormView):
             success_urls = {"create_new": reverse_lazy('create'),
                               "delete": reverse_lazy('delete')}
    """
    success_urls = {}  

    def form_valid(self, form):
        """ Form is valid: Pick the url and redirect.
        """

        for name in self.success_urls:
            if name in form.data:
                self.success_url = self.success_urls[name]
                break

        return HttpResponseRedirect(self.get_success_url())

    def get_success_url(self):
        """
        Returns the supplied success URL.
        """
        if self.success_url:
            # Forcing possible reverse_lazy evaluation
            url = force_text(self.success_url)
        else:
            raise ImproperlyConfigured(
                _("No URL to redirect to. Provide a success_url."))
        return url

#5


0  

one url to the same view! like so!

同一个视图的一个url !像这样!

###urls.py###
url(r'^$', views.landing.as_view(), name = 'landing'),

####views.py####
class landing(View):
    template_name = '/home.html'
    form_class1 = forms.pynamehere1
    form_class2 = forms.pynamehere2
        def get(self, request):
            form1 = self.form_class1(None)
            form2 = self.form_class2(None)
            return render(request, self.template_name, { 'register':form1, 'login':form2,})

         def post(self, request):
             if request.method=='POST' and 'htmlsubmitbutton1' in request.POST:
                    ## do what ever you want to do for first function ####
             if request.method=='POST' and 'htmlsubmitbutton2' in request.POST:
                     ## do what ever you want to do for second function ####
                    ## return def post###  
             return render(request, self.template_name, {'form':form,})


####/home.html####
#### form 1 ####
<form action="" method="POST" >
  {% csrf_token %}
  {{ register.as_p }}
<button type="submit" name="htmlsubmitbutton1">Login</button>
</form>
#### form 2 ####
<form action="" method="POST" >
  {% csrf_token %}
  {{ login.as_p }}
<button type="submit" name="htmlsubmitbutton2">Login</button>
</form>