如何解决 Flask 中使用 WTForm 时自定 Button 却在页面总被 Div 包裹住的问题


wtform中,我想定制一个button。

参考官方文档编写了 ButtonFiled() ButtonWidget(object) 以及 ButtonInput(Input) .

为什么我用了与库中一摸一样的代码,只是改了个函数名字,在页面生成的却总会被包裹在一个 DIV 中?且会被加上一个Label。

效果如图:
图片描述

我的代码如下:


 # !/usr/bin/env python
# coding: utf-8
'''

'''
from werkzeug.utils import escape
from wtforms import BooleanField,Field
from wtforms.widgets import HTMLString, html_params, Input, SubmitInput
from wtforms.compat import text_type

__author__ = 'Jux.Liu'


class ButtonWidget(object):
    '''
    用于显示按钮(button)的部件(widget)
    '''
    def __call__(self, field, **kwargs):
        kwargs.setdefault('name', field.name)
        kwargs.setdefault('value', field.value)
        kwargs.setdefault('type', "submit")
        return HTMLString('<button %s>%s</button>' % (
            html_params(**kwargs),
            escape(field._value())
            ))


class ButtonInput(Input):
    """
    Renders a submit button.

    The field's label is used as the text of the submit button instead of the
    data on the field.
    """
    input_type = 'submit'

    def __call__(self, field, **kwargs):
        kwargs.setdefault('value', field.label.text)
        return super(ButtonInput, self).__call__(field, **kwargs)


class ButtonOneField(BooleanField):
    '''
    定义可以将按钮(button)用于 Flask 表单(form)的域(field)
    '''
    widget = SubmitInput()


class ButtonTwoField(Field):
    '''
    定义可以将按钮(button)用于 Flask 表单(form)的域(field)
    '''
    widget = ButtonWidget()

    def __init__(self, text, name, value, **kwargs):
        super(ButtonTwoField, self).__init__(**kwargs)
        self.text = text
        self.value = value
        self.name = name

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

官方库代码截取如下:


 class SubmitField(BooleanField):
    """
    Represents an ``<input type="submit">``.  This allows checking if a given
    submit button has been pressed.
    """
    widget = widgets.SubmitInput()
class BooleanField(Field):
    """
    Represents an ``<input type="checkbox">``.

    :param false_values:
        If provided, a sequence of strings each of which is an exact match
        string of what is considered a "false" value. Defaults to the tuple
        ``('false', '')``
    """
    widget = widgets.CheckboxInput()
    false_values = ('false', '')

    def __init__(self, label=None, validators=None, false_values=None, **kwargs):
        super(BooleanField, self).__init__(label, validators, **kwargs)
        if false_values is not None:
            self.false_values = false_values
    def _value(self):
        if self.raw_data:
            return text_type(self.raw_data[0])
        else:
            return 'y'

class SubmitInput(Input):
    """
    Renders a submit button.

    The field's label is used as the text of the submit button instead of the
    data on the field.
    """
    input_type = 'submit'

    def __call__(self, field, **kwargs):
        kwargs.setdefault('value', field.label.text)
        return super(SubmitInput, self).__call__(field, **kwargs)


update:
出现这个问题的情况是使用 wtf.quick_form()时出现的,如果直接调用 form.button,那么生成的按钮是正常的。
update:
经测试,在ButtonTwoField(Field)的构造函数中,增加对于label的设定,可以将label改为空,但是依旧会被div包裹住.


 import wtforms import Label
class ButtonTwoField(Field):
    '''
    定义可以将按钮(button)用于 Flask 表单(form)的域(field)
    '''
    widget = ButtonWidget()

    def __init__(self, text, name, value, **kwargs):
        super(ButtonTwoField, self).__init__(**kwargs)
        self.label=Label(field_id=999, text='' )
        self.text = text
        self.value = value
        self.name = name

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

div python flask wtforms

hulucc 9 years, 10 months ago

你提到了 wtf.quick_form() , 这个应该是 flask-bootstrap 中的方法, 这个方法是经过包装了的, 你可以看看:

路径: flask-bootstrap/flask_bootstrap/templates/bootstrap/wtf.html

hcwjohn answered 9 years, 10 months ago

Your Answer