基于点击按钮验证WTForm表单 [英] Validate WTForm form based on clicked button
问题描述
在我的表单中,我有两个用于提交表单的按钮。一个按钮删除选定的文件(在表格中显示,一个复选框为一个对象),另一个按钮用于删除选择的文件。
删除时选择文件,不验证是必要的(除了检查至少有一个文件已被选中)。但是,为了处理,我需要确保只有一个特定扩展名的文件。基本上,我需要根据用户点击哪个按钮来进行不同的验证过程。
我该如何做到最好?我知道我可以在视图中执行验证,但是我更愿意在表单中验证它,因为它更干净。
以下是有问题的表单:
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,HiddenSubmitted):
允许用户选择哪些对象应该是
处理/删除/不管。
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屋!