基于点击按钮验证WTForm表单 [英] Validate WTForm form based on clicked button

查看:154
本文介绍了基于点击按钮验证WTForm表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的表单中,我有两个用于提交表单的按钮。一个按钮删除选定的文件(在表格中显示,一个复选框为一个对象),另一个按钮用于删除选择的文件。



删除时选择文件,不验证是必要的(除了检查至少有一个文件已被选中)。但是,为了处理,我需要确保只有一个特定扩展名的文件。基本上,我需要根据用户点击哪个按钮来进行不同的验证过程。



我该如何做到最好?我知道我可以在视图中执行验证,但是我更愿意在表单中验证它,因为它更干净。



以下是有问题的表单:

  class ButtonWidget(object):
方便显示按钮的小部件

def __call __(self,field,** kwargs):
如果field.name不是None:
kwargs.setdefault('name',field.name)
如果field.value是不是:
kwargs.setdefault('value',field.value)
kwargs.setdefault('type',submit)
return HTMLString('< button%s>% (Field._value())
))

class ButtonField(Field){
html_params(** kwargs),
escape(field._value())
) :
一个方便使用按钮的字段。

widget = ButtonWidget()

def __init __(self,text = None ,name = None,value = None,** kwargs):
super(ButtonField,self).__ init __(** kwargs)
self.text = text
self.value = value
如果name不是None:
self.name =名称

def _value(self):
返回str(self.text)

类MultiCheckboxField(SelectMultipleField):

多选,除了显示复选框列表。

迭代该字段将产生子字段,允许自定义渲染
封闭的复选框字段。

widget = ListWidget(prefix_label = False)
option_widget = CheckboxInput()

ProcessForm(Form,Hid​​denSubmitted):

允许用户选择哪些对象应该是
处理/删除/不管。


PROCESS =0
DELETE =-1

files = MultiCheckboxField(Select,coerce = int, validators = [
Required()
))#这是可供选择的文件列表
process_button = ButtonField(Process,name =action,value = PROCESS)
delete_button = ButtonField(Delete,name =action,value = DELETE)
$ b $ validate_files(form,field):
#如何检查按钮被点击在这里?
pass


解决方案

注意关于HTML中的按钮是只有被按下的按钮才会将其数据发送回服务器,所以你可以用 if form.process_button.data 在一般情况下,一切都将起作用。

在您的具体情况中,由于您的两个按钮从相同的基础参数名称( action ),您将需要检查一个按钮字段中的数据是否是您期望的:

  def validate_files(form,field):
#如果ButtonFields使用不同的名字,那么这只是
#如果form.process_button.data:
如果form.process_button。 data == ProcessForm.PROCESS:
#然后用户点击process_button
else:
#用户点击delete_button


On my form, I have two buttons that I use for submitting the form. One button deletes selected files (presented in a table, one checkbox to an object) and the other selects them for processing.

When the files are selected on deletion, no validation is necessary (beyond checking that at least one file has been selected). However, for processing I need to make sure that there is exactly one file of a certain extension. Basically, I need different validation processes based on which button the user clicked.

How can I best do this? I know I can perform validation in the view, but I would much prefer validating this inside the form, since it's cleaner.

Here's the forms in question:

class ButtonWidget(object):
    """A widget to conveniently display buttons.
    """
    def __call__(self, field, **kwargs):
        if field.name is not None:
            kwargs.setdefault('name', field.name)
        if field.value is not None:
            kwargs.setdefault('value', field.value)
        kwargs.setdefault('type', "submit")
        return HTMLString('<button %s>%s</button>' % (
            html_params(**kwargs),
            escape(field._value())
            ))

class ButtonField(Field):
    """A field to conveniently use buttons in flask forms.
    """
    widget = ButtonWidget()

    def __init__(self, text=None, name=None, value=None, **kwargs):
        super(ButtonField, self).__init__(**kwargs)
        self.text = text
        self.value = value
        if name is not None:
            self.name = name

    def _value(self):
        return str(self.text)

class MultiCheckboxField(SelectMultipleField):
    """
    A multiple-select, except displays a list of checkboxes.

    Iterating the field will produce subfields, allowing custom rendering of
    the enclosed checkbox fields.
    """
    widget = ListWidget(prefix_label=False)
    option_widget = CheckboxInput()

class ProcessForm(Form, HiddenSubmitted):
    """
    Allows the user to select which objects should be
    processed/deleted/whatever.
    """

    PROCESS = "0"
    DELETE = "-1"

    files = MultiCheckboxField("Select", coerce=int, validators=[
        Required()
        ]) # This is the list of the files available for selection
    process_button = ButtonField("Process", name="action", value=PROCESS)
    delete_button = ButtonField("Delete",  name="action", value=DELETE)

    def validate_files(form, field):
        # How do I check which button was clicked here?
        pass

解决方案

The key thing to note about buttons in HTML is that only the button that was pressed sends its data back to the server. So you can just check if the button's data field is set using if form.process_button.data an things will work in the general case.

In your particular case, since both of your buttons pull their data from the same underlying parameter name (action) you will need to check that the data in one of your button fields is what you would expect:

def validate_files(form, field):
    # If the ButtonFields used different names then this would just be
    # if form.process_button.data:
    if form.process_button.data == ProcessForm.PROCESS:
        # Then the user clicked process_button
    else:
        # The user clicked delete_button

这篇关于基于点击按钮验证WTForm表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆