Flask-WTForms 更改提交的日期字段值

Nic*_*ask 1 python flask-wtforms

我通过flask-WTF 扩展使用WTForms。我想在提交后更改日期字段的值。下面是一个例子:

class ExampleForm1(Form):
    date1 = DateField('Date', description = 'Select date..')
    submit_button = SubmitField('OK')

@app.route("/exampleform1", methods=['GET', 'POST'])
def example1():
    form = ExampleForm1()
    if request.method == 'POST' and form.validate():
            print str(form.date1)
            print form.date1.data

            form.date1.process_data(date(2000, 01, 01))
            print str(form.date1)
            print form.date1.data
            return render_template('example1.html', form=form)

    form.date1.process_data(date.today())
    return render_template('example1.html', form=form)
Run Code Online (Sandbox Code Playgroud)

这是输出:

<input id="date1" name="date1" type="date" value="2015-03-15">
2015-03-15
<input id="date1" name="date1" type="date" value="2015-03-15"> <-- This isn't updated
2000-01-01 <-- this is updated
Run Code Online (Sandbox Code Playgroud)

该网页仍显示 2015-03-15 而不是 2000-01-01。我错过了什么?

谢谢!

sea*_*ers 5

所以,是的......两年后,我也不止一次受到这个问题的影响。最后,令人沮丧的是它的底部(我不知道为什么这不为人所知/这个问题尚未得到回答),但是如果您查看 ( DateTimeField,它DateField继承自) 的来源,

https://github.com/wtforms/wtforms/blob/master/wtforms/fields/core.py#L732

def _value(self):
    if self.raw_data:
        return ' '.join(self.raw_data)
    else:
        return self.data and self.data.strftime(self.format) or ''
Run Code Online (Sandbox Code Playgroud)

如果raw_data设置,它返回那个。

因此,您可以设置raw_data为 None,然后将其作为该字段的值返回,遵循面包屑路径,

https://github.com/wtforms/wtforms/blob/master/wtforms/fields/core.py#L141

https://github.com/wtforms/wtforms/blob/master/wtforms/meta.py#L47

https://github.com/wtforms/wtforms/blob/master/wtforms/widgets/core.py#L177

def __call__(self, field, **kwargs):
    kwargs.setdefault('id', field.id)
    kwargs.setdefault('type', self.input_type)
    if 'value' not in kwargs:
        kwargs['value'] = field._value()
    return HTMLString('<input %s>' % self.html_params(name=field.name, **kwargs))
Run Code Online (Sandbox Code Playgroud)

但更好的是“正确”处理它,

https://github.com/wtforms/wtforms/blob/master/wtforms/fields/core.py#L256

    ...
    if formdata is not None:
        if self.name in formdata:
              self.raw_data = formdata.getlist(self.name)
    ...
Run Code Online (Sandbox Code Playgroud)

进程正在ImmutableMultiDict等待 ,所以对于你的情况,而不是,

form.date1.process_data(date(2000, 01, 01))
Run Code Online (Sandbox Code Playgroud)

你做了一个“完整”的过程,传入一个正确形成的ImmutableMultiDict

form.date1.process(ImmutableMultiDict(
  [('date1', date(2000, 01, 01).strftime(form.date1.format))]))
Run Code Online (Sandbox Code Playgroud)

它期望它的字段是字符串,并且 a DateField, 是字段的正确格式,所以这就是为什么我要做一个strftime在它上面并使用它自己的格式,所以我们“有点”作弊。

为了帮助这个过程,当我在几个不同的地方使用它时,我使用了这个辅助函数,

def full_field_process(field, val):
    field.process(ImmutableMultiDict([(field.short_name, val)]))
Run Code Online (Sandbox Code Playgroud)

在你的情况下,会被称为,

full_field_process(
    form.date1,
    date(2000, 01, 01).strftime(form.date1.format))
Run Code Online (Sandbox Code Playgroud)

令人沮丧的是,当您执行常规流程时,这并不容易,并且您没有标志或可以执行原始流程的东西,但是 c'est la vie。你就是这样做的,所以现在这个,

<input id="date1" name="date1" type="date" value="2015-03-15">
2015-03-15
<input id="date1" name="date1" type="date" value="2000-01-01">
2000-01-01
Run Code Online (Sandbox Code Playgroud)

是正确的。