了解wtforms StringField实现

时间:2016-10-21 22:05:36

标签: python flask wtforms flask-wtforms

我正在使用Flask中的wtforms,我特别感兴趣的是理解StringField类的实现的某些方面。

所以我有以下用户定义的类:

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


class LoginForm(Form):

    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])

现在我像这样实例化这个类:

from flask import request
form = LoginForm(request.form)

现在我这样做了:

  

form.username.data

我基本上是指<​​em>用户名对象的 data 成员(它是 StringField 类的对象)。对吗?

现在我想了解这个数据的来源?

所以我继续执行 StringFiled 类,我在以下位置找到它:

  

站点包/ wtforms /场/ core.py

core.py是一个非常大的文件,无法在此处粘贴

现在在core.py中, StringField类的实现是:

class StringField(Field):
    """
    This field is the base for most of the more complicated fields, and
    represents an ``<input type="text">``.
    """
    widget = widgets.TextInput()

    def process_formdata(self, valuelist):
        if valuelist:
            self.data = valuelist[0]
        else:
            self.data = ''

    def _value(self):
        return text_type(self.data) if self.data is not None else ''

现在,在本课程中,数据成员出现的第一个位置(实际上已设置)位于行

self.data = valuelist[0]

在process_formdata()中,它附加到调用对象(在我们的例子中是对象用户名),然后最终在_value()中返回。

然而,process_formdata()本身永远不会在整个core.py文件中的任何地方被调用,除了1个地方,即Field类方法(StringField继承) process()

但重点是, process()方法本身并没有在整个core.py中的任何地方被调用。

所以问题是

当执行该操作的代码行完全没有达到时, self.data 的确切设置如何?我肯定错过了一些东西。请帮助我更好地理解这一点。

1 个答案:

答案 0 :(得分:0)

确定。凉。通过学习如何使用pycharm调试Flask应用程序然后单步执行某些代码来实现这一点。调试中的一个技巧部分是配置调试设置以传递运行应用程序所需的参数。在我的情况下,应用程序是使用flask_script中的Manager模块运行的:

from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from project import app, db

app.config.from_object('config.DevelopmentConfig')
migrate = Migrate(app, db)
manager = Manager(app)

manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()

并且以这种方式运行runserver需要作为参数给出,例如:

  

python manage.py runserver

所以这个 runserver 参数也需要在调试期间给出。 所以要做到这一点(在你的行 form = LoginForm(request.form)中放置一个断点后,实际上一切都开始了):

  1. 转到保存上述内容的主运行文件文件,即manage.py 代码。
  2. 在主菜单中转到运行 - &gt; 调试
  3. 在弹出的窗口中,选择编辑配置选项
  4. 在RHS窗格中,在脚本参数中将值指定为 runserver
  5. 应用,然后单击调试。
  6. 现在,当您在浏览器中提交表单时,您将点击上面的断点。现在您可以简单地进入/覆盖代码(根据需要)并按照执行流程来跟踪实际调用方法的时间。

    所以这里的process()基本上是从以下路径调用的:

      

    站点包/ wtforms / forms.py

    并且调用它的代码段是:

        for name, field, in iteritems(self._fields):
            if obj is not None and hasattr(obj, name):
                field.process(formdata, getattr(obj, name))
            elif name in kwargs:
                field.process(formdata, kwargs[name])
            else:
                field.process(formdata)
    

    ,由于用户定义文件forms.py

    中的这一行,上面的文件出现在图片中
      

    来自wtforms import StringField,PasswordField