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

Python 如何构建多个提交按钮django表单?,python,django,button,django-forms,submit,Python,Django,Button,Django Forms,Submit,我有一个表格,其中一个用于输入电子邮件,两个用于订阅和取消订阅时事通讯的提交按钮: <form action="" method="post"> {{ form_newsletter }} <input type="submit" name="newsletter_sub" value="Subscribe" /> <input type="submit" name="newsletter_unsub" value="Unsubscribe" /> </

我有一个表格,其中一个用于输入电子邮件,两个用于订阅和取消订阅时事通讯的提交按钮:

<form action="" method="post">
{{ form_newsletter }}
<input type="submit" name="newsletter_sub" value="Subscribe" />
<input type="submit" name="newsletter_unsub" value="Unsubscribe" />
</form>
我必须写我自己的clean_电子邮件方法,我需要知道表单是通过哪个按钮提交的。但是提交按钮的值不在
self.cleaned\u data
字典中。
我是否可以获取其他按钮的值?

您可以使用
clean\u email
方法中的
self.data
在验证前访问POST数据。它应该包含一个名为
newsletter\u sub
newsletter\u 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
例如:


你也可以这样做

 <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>

这是一个老问题了,不过我也遇到了同样的问题,找到了一个适合我的解决方案:我写了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
从django.http导入HttpResponseRedirect
类MultiRedirectMixin(对象):
"""
支持提交特定成功重定向的mixin。
指定一个成功url,或为dict提供
将模板中给定的操作作为键提交
例子:
在模板中:
视图:
MyMultiSubmitView(MultiRedirectMixin,forms.FormView):
success_url={“create_new”:reverse_lazy('create'),
“删除”:反向_lazy('delete')}
"""
成功_url={}
def表单_有效(自身、表单):
“”表单有效:选择url并重定向。
"""
对于self.success\u URL中的名称:
如果名称在form.data中:
self.success\u url=self.success\u url[名称]
打破
返回HttpResponseRedirect(self.get_success_url())
def get_success_url(自我):
"""
返回提供的成功URL。
"""
如果self.success\u url:
#强制可能的反向计算
url=force\u text(self.success\u url)
其他:
提高配置不当(
_(“没有要重定向到的URL。请提供一个成功的URL。”)
返回url
同一视图的一个url! 像这样

url.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
{%csrf_令牌%}
{{register.as_p}}
登录
{%csrf_令牌%}
{{login.as_p}
登录

您能给出一个带注释的示例吗?这真的很有帮助,我不认为
clean
真的不是做模型级逻辑的合适地方。它专门用于清理表单并查找跨越多个输入的任何
ValidationError
s。斯文的答案更加正确,但仍然不一定是安全风险的最佳答案!在验证表单之前使用表单数据在数据库中进行更改是危险的。您可能需要根据按下的按钮运行不同类型的验证。在这种情况下,没有“安全”影响。form1.as\p何时使用此??在视图中,在检查表单的有效性时,我希望我能做。。。form1.is_valid()然后执行此操作,form2.is_valid()执行此操作..请求在clean_xxx验证方法中可用吗?应使用哪种方法?@JonMcClung inside
def post(self,request,*args,**kwargs)
。您将在何处以及如何准确使用多重定向mixin?请举例说明。我应该如何引用其他html文件中的特定视图href=“{%url”appname:viewname“%”我应该为视图中的表单提供什么。py为什么要在POST函数中测试该方法是否为POST?如果http方法是post,则基于类的视图只能调用post函数。我似乎不记得为什么这是4年前的事了。然而,我似乎记得这是必要的,因为有一种循环行动方法,其中一种形式正在提交,而不是另一种形式。但也不完全确定。
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
url(r'^$', views.landing.as_view(), name = 'landing'),
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>