【问题标题】:Pass custom object to WTForm将自定义对象传递给 WTForm
【发布时间】:2016-12-16 12:33:24
【问题描述】:

我需要将一个对象从我的数据库传递到我的表单,我想从中读取默认值。我当前的代码如下所示:

我的初始化:

form = EditEventForm(event)

还有我的表单类:

class EditEventForm(FlaskForm):
    def __init__(self, event):
        self.event = event

    name = StringField('Name', validators=[DataRequired()],     default=self.event.name)
    description = TextAreaField('Description', validators=[DataRequired()], default=self.event.description)
    street = StringField('Street and number', validators=[DataRequired()], default=self.event.street)
    city = StringField('City', validators=[DataRequired()], default=self.event.city)
    time = StringField('Time', validators=[DataRequired()], default=self.event.time)

但显然,表单无法访问自身上下文。有没有其他方法可以实现它,以便我的字段可以从传递的对象中读取数据?

【问题讨论】:

  • 您在寻找FlaskForm(obj=…)吗?
  • @Kay 看起来不错,但我如何从表单中访问它?只是 obj.attribute?
  • 表单与对象无关,反之亦然。用FlaskForm(obj=…)读出一个对象,用FlaskForm.populate_obj(…)设置一个对象的值。

标签: python python-3.x flask wtforms flask-wtforms


【解决方案1】:

如果您的任务只是用默认数据填充表单,您可以这样做:

from flask_wtf import Form
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired

class EditEventForm(Form):
    name = StringField('Name', validators=[DataRequired()])
    description = TextAreaField('Description', validators=[DataRequired()])
    street = StringField('Street and number', validators=[DataRequired()])
    city = StringField('City', validators=[DataRequired()])
    time = StringField('Time', validators=[DataRequired()])

然后用所需数据填充新创建的表单

form = EditEventForm()
form.name.data = event.name
form.description.data = event.description
form.street.data = event.street
form.city.data = event.city
form.time.data = event.time

编辑

正如 cmets 中所建议的,上述模式很糟糕,因为当模型或表单对象发生更改时,必须跟踪所有创建表单的实例。可以改用这样的东西:

# attributes of the event object matching form field names will be used for field values
form = EditEventForm(obj=event)

# populates the attributes of the passed obj with data from the form’s fields
form.populate_obj(event)

来自documentation

注意:这是破坏性操作;任何与字段同名的属性都将被覆盖。谨慎使用。

【讨论】:

  • 哦不知道,但是是的,很明显,非常感谢 :)
  • 这是一个非常糟糕的模式。如果表单或对象类发生更改,则需要跟踪表单创建的所有实例。这使得项目无法维护。
  • Kay 所说的 - 如果您必须做这样的事情,请在表单的 __init__ 中进行,而不是在外面。
【解决方案2】:

来自the FineManual

init(formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs) 参数:
(...) obj - 如果 formdata 为空或未提供,则检查此对象是否匹配表单字段名称的属性,这些属性将用于字段值。

【讨论】:

    猜你喜欢
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多