了解 wtforms StringField 实现
Understanding the wtforms StringField implementation
我正在使用 Flask 中的 wtforms,特别有兴趣了解 StringField 实现的某些方面 class。
所以我有以下用户定义 class:
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()])
现在我像这样实例化 class:
from flask import request
form = LoginForm(request.form)
现在当我这样做时:
form.username.data
我基本上指的是 data 对象的 username 成员(它是 StringField 的一个对象 class)。对吗?
现在我想了解这个 数据 来自哪里?
所以我继续实施 StringFiled class,我在以下位置找到了它:
site-packages/wtforms/fields/core.py
core.py文件比较大无法粘贴
现在 core.py StringField class 的实现是:
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 ''
现在在这个 class 中,data 成员出现的第一个位置(实际上已设置)在
行中
self.data = valuelist[0]
在 process_formdata() 中附加到调用对象(在我们的例子中是对象 用户名),然后它最终在 _value( ).
但是 process_formdata() 本身在整个 core.py 文件的任何地方都不会被调用,除了 1 个地方,即在 Field class 方法(StringField 继承)中进程()
但重点是,process() 方法本身并没有真正在整个 core.py 的任何地方被调用。
所以问题是:
当执行此操作的代码行根本没有达到时,self.data 究竟是如何设置的?我肯定错过了什么。请帮助我更好地理解这一点。
好的。凉爽的。通过学习如何使用 pycharm 调试 Flask 应用程序,然后单步执行 into/over 一些代码,得到了这个。调试中的一个技巧部分是配置调试设置以传递 运行 应用程序所需的参数。在我的例子中,应用程序是 运行 通过使用 flask_script 中的管理器模块作为:
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()
虽然 运行 以这种方式 运行server 需要作为参数给出,例如:
python manage.py runserver
所以这个 运行server 参数也需要在调试期间给出。
所以要这样做(在 form = LoginForm(request.form) 行中放置一个断点后,实际上一切都从这里开始):
- 转到主 运行 文件,即 manage.py,其中包含上述内容
代码。
- 转到主菜单中的运行 -> 调试
- 从弹出的window中,选择编辑配置选项
- 在 RHS 窗格中,在 Script Parameters 中将值设为 运行server
- 应用然后点击调试。
现在当您在浏览器中提交表单时,您会遇到上面设置的断点。现在您可以简单地单步执行 into/over 代码(根据需要)并按照执行流程跟踪实际调用方法的时间。
所以这里的 process() 基本上是从以下路径调用的:
site-packages/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
from wtforms import StringField, PasswordField
我正在使用 Flask 中的 wtforms,特别有兴趣了解 StringField 实现的某些方面 class。
所以我有以下用户定义 class:
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()])
现在我像这样实例化 class:
from flask import request
form = LoginForm(request.form)
现在当我这样做时:
form.username.data
我基本上指的是 data 对象的 username 成员(它是 StringField 的一个对象 class)。对吗?
现在我想了解这个 数据 来自哪里?
所以我继续实施 StringFiled class,我在以下位置找到了它:
site-packages/wtforms/fields/core.py
core.py文件比较大无法粘贴
现在 core.py StringField class 的实现是:
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 ''
现在在这个 class 中,data 成员出现的第一个位置(实际上已设置)在
行中self.data = valuelist[0]
在 process_formdata() 中附加到调用对象(在我们的例子中是对象 用户名),然后它最终在 _value( ).
但是 process_formdata() 本身在整个 core.py 文件的任何地方都不会被调用,除了 1 个地方,即在 Field class 方法(StringField 继承)中进程()
但重点是,process() 方法本身并没有真正在整个 core.py 的任何地方被调用。
所以问题是:
当执行此操作的代码行根本没有达到时,self.data 究竟是如何设置的?我肯定错过了什么。请帮助我更好地理解这一点。
好的。凉爽的。通过学习如何使用 pycharm 调试 Flask 应用程序,然后单步执行 into/over 一些代码,得到了这个。调试中的一个技巧部分是配置调试设置以传递 运行 应用程序所需的参数。在我的例子中,应用程序是 运行 通过使用 flask_script 中的管理器模块作为:
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()
虽然 运行 以这种方式 运行server 需要作为参数给出,例如:
python manage.py runserver
所以这个 运行server 参数也需要在调试期间给出。 所以要这样做(在 form = LoginForm(request.form) 行中放置一个断点后,实际上一切都从这里开始):
- 转到主 运行 文件,即 manage.py,其中包含上述内容 代码。
- 转到主菜单中的运行 -> 调试
- 从弹出的window中,选择编辑配置选项
- 在 RHS 窗格中,在 Script Parameters 中将值设为 运行server
- 应用然后点击调试。
现在当您在浏览器中提交表单时,您会遇到上面设置的断点。现在您可以简单地单步执行 into/over 代码(根据需要)并按照执行流程跟踪实际调用方法的时间。
所以这里的 process() 基本上是从以下路径调用的:
site-packages/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
from wtforms import StringField, PasswordField