根据点击的按钮验证WTForm表单

3 投票
1 回答
5942 浏览
提问于 2025-04-18 04:10

在我的表单上,有两个按钮用来提交表单。一个按钮是用来删除选中的文件(这些文件在一个表格中展示,每个文件旁边有一个复选框),另一个按钮是用来选择文件进行处理。

当用户选择要删除的文件时,不需要太多验证,只要检查至少选中了一个文件就可以了。不过,如果是要处理文件,我需要确保选中的文件中有且只有一个是特定格式的文件。简单来说,我需要根据用户点击的按钮来进行不同的验证。

我该怎么做比较好呢?我知道可以在视图中进行验证,但我更希望在表单内部进行验证,这样看起来更整洁。

以下是相关的表单代码:

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

1 个回答

6

在HTML中,按钮的一个关键点是,只有被按下的按钮会把它的数据发送回服务器。所以你只需要检查按钮的data字段是否被设置,比如用if form.process_button.data,这样一般情况下就能正常工作。

在你的具体情况下,因为你两个按钮的数据都是从同一个参数名(action)获取的,所以你需要检查其中一个按钮字段的数据是否是你所期望的:

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

撰写回答