Flask WTForms 在 validate_on_submit() 上总是给出 false

2023-12-02

我使用 wtforms 创建了一个注册表单。我在其中使用 FormField,这样我就不必再次重复表单的某些元素。但每当我单击“提交”按钮时,它总是在 validate_on_submit 方法调用上给出 false。不明白为什么会发生这种情况。

My form.py如下:

class ProfileInfoForm(Form):
    firstname = TextField('firstname', validators=
                          [validators.Required("Please enter First name.")])
    lastname = TextField('lastname', validators=
                         [validators.Required("Please enter Last name.")])
    email = EmailField('email', validators=
                       [validators.Required("Please enter your valid email.")])
    gender = RadioField('gender', validators=
                        [validators.Required("Please select gender")],
                        choices=[('female', 'Female'), ('male', 'Male')])
    dob = TextField('dob', validators=
                    [validators.Required("Please select date of birth.")])
    languages = SelectMultipleField('languages', choices=[('', '')],
                                    validators=
                                    [validators.Required("Please select\
                                                         atleast one \
                                                         language.")])


class RegistrationForm(Form):
    profilefield = FormField(ProfileInfoForm)
    password = PasswordField('password',
                             validators=
                             [validators.Required("Please enter password."),
                              validators.Length(min=8),
                              validators.EqualTo('confirm_password',
                                                 message='Password and confirm\
                                                 password must match')])
    confirm_password = PasswordField('confirm_password',
                                     validators=
                                     [validators.Required("Please enter\
                                                          confirm password.")])
    tnc = BooleanField('tnc', validators=
                       [validators.Required("Please select Terms and \
                                            Conditions")], default=False)

    submit = SubmitField('Create My Account')

Signup方法如下:

@module.route('/signup', methods=['GET', 'POST'])
  @handle_error
  def signup():
      if hasattr(g, 'user') and g.user:
          # TODO: do some operations if needed else keep it blank
          return redirect(url_for('index'))
      else:
          signup_form = RegistrationForm()
          # Add choices for the user
          signup_form.profilefield.languages.choices = getLanguages()
          if signup_form.validate_on_submit():
              firstname = signup_form.profilefield.firstname.data
              lastname = signup_form.profilefield.lastname.data
              email = signup_form.profilefield.email.data
              password = signup_form.password.data
              #  confirm_password = signup_form.confirm_password.data
              gender = signup_form.profilefield.gender.data
              dob = signup_form.profilefield.dob.data
              languages = signup_form.profilefield.languages.data
              tnc = signup_form.tnc.data

              payload = {'firstname': firstname, 'lastname': lastname,
                         'email': email, 'password': password, 'gender': gender,
                         'dob': dob, 'languages': languages,
                         'tnc': ('1' if tnc else '0')}
              try:
                  buildApiUrl = BuildApiUrl()
                  response = requests.post(buildApiUrl.getUrl("user", "signup"),
                                           data=payload)

                  if response.status_code == requests.codes.ok:
                      data = json.loads(response.text)
                      if 'status' in data and data['status'] != 200:
                          flash(data['message'], category="error")
                      else:
                          flash(data['message'] +
                                ': Your account is created successfully! ' +
                                'Please login to your account!',
                                category="success")
                          return redirect(url_for('index'))
              except requests.exceptions.RequestException:
                  flash('Internal Server side error occured', category="error")
                  return redirect(url_for('server_error', e='500'))

      return render_template('public/index.html',
                             signup_form=signup_form, login_form=LoginForm())

HTML 表单存在于要点在这里

仅供参考:我将所有必填字段与所需的实际数据放在一起。当我调用 validate_on_submit() 时仍然出现错误。我的代码有什么问题?

编辑: getLanguages 是一种从数据库检索语言并将其放入选择列表的方法。此功能按预期发生,我可以获得语言列表。

编辑2:在这里意识到一件事。这是由于 FormField 造成的,因为我通过将 ProfileInfoForm() 的所有字段添加到 RegistrationForm() 方法中进行了测试,一切正常,我可以注册。所以 FormField 或我使用它的方式存在一些问题,但不确定哪里出了问题。

发现问题不在于 FormField,而在于我的 ProfileInfoForm()。它总是返回 false。还没有理由,但我想我可能必须为此编写自己的验证。有什么想法吗?

Edit:

在转储时我得到以下信息(此处使用 pprint):

{'SECRET_KEY': '1e4c35233e50840483467e8d6cfe556c',
 '_errors': None,
 '_fields': {'csrf_token': <wtforms.ext.csrf.fields.CSRFTokenField object at 0x2207290>,
             'dob': <wtforms.fields.simple.TextField object at 0x2207650>,
             'email': <flask_wtf.html5.EmailField object at 0x22074d0>,
             'firstname': <wtforms.fields.simple.TextField object at 0x2207350>,
             'gender': <wtforms.fields.core.RadioField object at 0x2207590>,
             'languages': <wtforms.fields.core.SelectMultipleField object at 0x2207710>,
             'lastname': <wtforms.fields.simple.TextField object at 0x2207410>},
 '_prefix': u'profilefield-',
 'csrf_enabled': True,
 'csrf_token': <wtforms.ext.csrf.fields.CSRFTokenField object at 0x2207290>,
 'dob': <wtforms.fields.simple.TextField object at 0x2207650>,
 'email': <flask_wtf.html5.EmailField object at 0x22074d0>,
 'firstname': <wtforms.fields.simple.TextField object at 0x2207350>,
 'gender': <wtforms.fields.core.RadioField object at 0x2207590>,
 'languages': <wtforms.fields.core.SelectMultipleField object at 0x2207710>,
 'lastname': <wtforms.fields.simple.TextField object at 0x2207410>}

Edit:

我挖掘了一下,发现生成错误是由于 csrf 令牌丢失。但我已经包括了{{ signup_form.hidden_tag() }}在我的 html 表单模板中。当我检查元素时,我可以在生成的 html 中看到隐藏标记,并且可以看到带有哈希值的 csrf_token 字段。那么这里出了什么问题呢?


我用以下函数解决了我的问题:

def __init__(self, *args, **kwargs):
    kwargs['csrf_enabled'] = False
    super(ProfileInfoForm, self).__init__(*args, **kwargs)

我在中添加了这个功能ProfileInfoForm()

问题是FormField包括csrf_token字段以及实际形式,即RegistrationForm还包括 csrf_token,所以有两个csrf_token哪些内容有待验证,并且只有一个以形式实际呈现。所以,我禁用了csrf_token in ProfileInfoForm所以当 FormField 渲染它时,它有csrf_token = False.

And RegistrationForm确实有csrf_token现在仍然启用,因此表单仍然安全。

我的猜测是这也需要在FormField以及。

仅供参考:由于我对 FormField 代码的解释,此解决方案可能是错误的。所以如果我在上面的解决方案中错了,请纠正我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flask WTForms 在 validate_on_submit() 上总是给出 false 的相关文章

随机推荐

  • 对 STL 字符串使用 fread/fwrite。这是对的吗?

    我有一个包含字符串的结构 像这样的东西 struct Chunk int a string b int c 因此 我想我无法使用 fread 和 fwrite 函数从文件中写入和读取此结构 因为字符串可能保留不同的内存容量 但这样的代码可以
  • 编辑音频/重新录制文件的一部分

    我希望用户能够在应用程序中录制音频 然后能够选择文件的一部分并重新录制 例如 也许他们最初录制 现在怎么样 棕色母牛 然后选择该结尾并重新录制 皱眉母猪 这将被合并到初始文件中 该文件将是 现在怎么样 皱眉母猪 这似乎比我想象的要困难得多
  • 应用程序网关 - 502 错误

    我已经按照 MS 文档设置了一个新的应用程序网关 我已经配置了后端池 它通过 FQDN 连接到应用程序服务 不知何故 每次浏览应用程序网关时 我都会立即收到 502 直接浏览网站没有任何问题 我已经解决了这个问题 这是解决方案 如果您的后端
  • 如何从 Java 读取 Oracle 数据库中的 CLOB 列

    我在数据库中有一个表 其中列的数据类型 STATUS 是 CLOB 我需要读取该 STATUS create table STATUS TABLE STATE ID number 20 0 STATUS clob 我正在尝试阅读如下 CLO
  • 在类层次结构中混合 Java 1.4 和 1.6 字节码

    先问问题 故事如下 在类层次结构中混合不同的字节码版本是否安全 有哪些风险 对于一种情况 C类扩展B B类扩展A类 A类实现接口I 我的问题将涉及以下示例场景 A 类编译为 Java 1 6 字节码 并具有 1 6 特性 如泛型等 继承人
  • 使用 Python + Selenium 选择 iframe

    所以 我对如何在 Selenium 中做到这一点感到非常困惑 并且在任何地方都找不到答案 所以我分享我的经验 我试图选择一个 iframe 但没有运气 或者无论如何都不能重复 HTML 是
  • 使用expressjs发布到远程URL

    我的 server js 中有这个 app post leadAPI ed function request response api post code here 在此发布请求中 我需要将请求正文中包含的数据发布到具有特定 URL 的外部
  • 在 Python 3 .4 中连接字符串和 int [重复]

    这个问题在这里已经有答案了 我是 Python 新手 所以我一直在进行自己的一组练习 以简单地开始记住基本函数和语法 我正在使用PyCharmIDE 和 Python 3 4 我在进行一些基本的字符串和整数连接练习时遇到了问题 下面的每个实
  • 动态创建/绘制图像以放入 Android 视图中

    我不确定我是否以 正确 的方式这样做 所以我也对其他选择持开放态度 这就是我想要实现的目标 我想要一个包含图表的视图 该图表应该由应用程序本身动态创建 图表应该是可缩放的 并且一开始可能会比屏幕大 800x600 左右 我打算从简单的开始
  • 如何在java中读取Doc或Docx文件? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我想用java读取word文件 import org apache poi poifs
  • 现代 JVM 实现中,instanceof 是如何实现的?

    由于在其他线程中完成的基准测试 参见https stackoverflow com a 397617 1408611 结果表明 Java 6 中的 instanceof 实际上相当快 这是如何实现的 我知道 对于单继承 最快的想法是进行一些
  • 在 PyQt5 中停止工作线程中的无限循环最简单的方法

    我打算有一个 GUI 其中一个 后来是三个 线程以可调间隔 例如 10 秒 从不同源读取实时数据 并在主窗口中绘制这些数据 我正在使用 PyQt5 和 python 3 6 读取是在工作线程中无限循环中执行的 如下所示 class Read
  • 在 Objective-C 中使用内联汇编对变量进行 ROL / ROR

    我想对 Objective C 程序中的变量执行 ROR 和 ROL 操作 然而 我无法做到这一点 我不是装配专家 这是我到目前为止所做的 uint8 t v1 uint8 t v2 v2 is either 1 2 3 4 or 5 as
  • 更改用户控件的动画

    我有一个简单的自定义窗口 下面的 XAML 首次加载时 它将向 grdContainer Children 集合添加一个用户控件 用户选择 操作将导致其他用户控件添加 删除到子集合中 一次加载一个 我试图做的是在加载新控件时提供一个简单的动
  • 在 Python 中检测两个数据数组的模式

    我正在尝试从中检测模式开盘 高位 低位 收盘 OHLC 数据 所以这就是我所做的 查找数据集上的局部最小值和最大值 通过将局部最小值和最大值数组转换为数字数组来标准化我的数据 其中每个数字都是与前一点的变化 到目前为止 一切正常 但我陷入了
  • 在抛出 OutOfMemoryException 之前调用 GC.Collect

    有什么方法可以在抛出 OutOfMemoryException 之前调用 GC Collect 吗 我想我正在寻找一种方法来执行以下代码流 Try to Allocate Memory On Pass Return Call GC Coll
  • Jenkins 中字符串参数的存储库 URL

    我正在构建一个脚本化的 Jenkins 管道 Jenkins 文件是从 git 存储库中获取的 我想参数化存储库 URL 我创建了一个字符串参数 我尝试访问 存储库 URL 字段中的字符串参数 但不起作用 我收到错误消息 指出该参数不是可识
  • Bing 拼写检查 API 仅适用于英语

    Trying 必应拼写检查 API 但它似乎无法在英语以外的语言中正常工作 拼写检查可用的语言 我尝试检查法语文本 但结果实际上会建议完美文本中的错误 反之亦然 意味着它也不会纠正文本中的错误 我试过检查这段文字 土地是一个内部固体 这就是
  • string.ToLower() 和 string.ToLowerInvariant()

    有什么区别以及何时使用什么 如果我总是使用会有什么风险ToLower 如果我总是使用会有什么风险ToLowerInvariant 根据当前的区域性 ToLower 可能会生成您不期望的特定于区域性的小写字母 比如生产 nfoi 上没有点而不
  • Flask WTForms 在 validate_on_submit() 上总是给出 false

    我使用 wtforms 创建了一个注册表单 我在其中使用 FormField 这样我就不必再次重复表单的某些元素 但每当我单击 提交 按钮时 它总是在 validate on submit 方法调用上给出 false 不明白为什么会发生这种