【问题标题】:Can't submit WTForms data into MySQL无法将 WTForms 数据提交到 MySQL
【发布时间】:2014-02-19 07:31:17
【问题描述】:

无法将 WTForms 数据提交到 MySQL 数据库,因为提交的数据仍在未绑定字段等内容中,尽管我尝试将其转换为字符串。不知道该怎么办。

我正在尝试使用 Flask 和 WTForms 创建注册表单。当我将数据(用户名、密码、电子邮件)放入 MySQL 数据库时出现以下错误:

我试过到处寻找,但没有任何地方可以解释我如何解决这个问题。以下是相关代码:

class User():
global cur
cur = config.conn.cursor()

def __init__(self, username, password, email):
    self.usr = username
    self.pwd = password
    self.mail = email

def database(self, username, password, email):
    u_p_e = cur.execute("INSERT into users (username, pwd, e-mail) VALUES ('%s', '%s', '%s')"
                                                               % (username, password, email))
    cur.commit()


class Register(Form):
    reg_username = TextField('Username', [validators.Length(min=1, max = 12)])
    username = str(reg_username)
    reg_password = PasswordField('Password', [
             validators.Required(),
             validators.EqualTo('confirm_password', message='Passwords do not match')
    ])

    confirm_password = PasswordField('Confirm Password')
    password = str(confirm_password)
    reg_email = TextField('Email', [validators.Length(min=6, max=35)])
    email = str(reg_email)

    enter_db = User(username, password, email)
    enter_db.database(username, password, email)

我是使用 Flask/WTForms 进行 Web 开发的新手。

【问题讨论】:

  • 我对 WTForms 一无所知,但这不可能是正确的:您在类级别的表单定义本身中处理所有数据库内容。您可能需要在处理表单的处理程序中执行此操作,它将接受 POST 数据并进行验证。

标签: python mysql flask wtforms flask-wtforms


【解决方案1】:

您的代码有两个问题。

第一个问题是你如何定义你的类。

class Register(Form):
    reg_username = TextField('Username', [validators.Length(min=1, max = 12)])
    username = str(reg_username)
    reg_password = PasswordField('Password', [
             validators.Required(),
             validators.EqualTo('confirm_password', message='Passwords do not match')
    ])

    confirm_password = PasswordField('Confirm Password')
    password = str(confirm_password)
    reg_email = TextField('Email', [validators.Length(min=6, max=35)])
    email = str(reg_email)

    enter_db = User(username, password, email)
    enter_db.database(username, password, email)

您对str 的调用发生在创建类并将reg_username、confirm_password 和reg_email 属性转换为字符串时。您在错误消息中看到的值是来自TextField.__str__ 的返回值。

然后将enter_db 附加为Register 的属性。 enter_db 是用 Register.username、Register.password 和 Register.email 的值实例化的 User。然后,仍然在创建类时,调用 Register.enter_db.database 并为其赋予与实例化 Register.enter_db 相同的值。

您在任何时候都不会为reg_username、confirm_password 和reg_email 字段赋值。这通常通过在实例化Register 时提供request.form 来完成,例如form = Register(request.form)。完成此操作后,您将能够通过form.reg_username.data 等访问每个字段的值。这部分通常发生在视图函数中。

您遇到的第二个问题是如何执行 SQL 语句。

"INSERT into users (username, pwd, e-mail) VALUES ('%s', '%s', '%s')"
                                                               % (username, password, email)

这使用字符串插值将username、password 和email 的值在执行之前直接放入语句中。除了这是一种不好的做法之外,其中一个值中的任何 ' 都会破坏您的陈述。这就是发生在您身上的事情,因为 TextField.__str__ 在字段名称周围包含单引号。

更好(更安全)的方法是使用参数化查询。虽然具体情况因驱动程序而异,但我相信? 是一个非常常见的实现。这会将您的查询更改为类似于

"INSERT into users (username, pwd, email) VALUES (?, ?, ?)"

然后将值传递给cur.execute

cur.execute("INSERT into users (username, pwd, email) VALUES (?, ?, ?)", (username, password, email))

解决这两个问题应该会让你走上正确的道路。

【讨论】:

    【解决方案2】:

    如Schema Object Names 中所述:

    MySQL 中的某些对象,包括数据库、表、索引、列、别名、视图、存储过程、分区、表空间和其他对象名称称为标识符。

    [ deletia ]

    标识符在内部转换为 Unicode。它们可能包含以下字符:

    • 不带引号的标识符中允许的字符:

      • ASCII:[0-9,a-z,A-Z$_](基本拉丁字母、数字 0-9、美元、下划线)

      • 扩展:U+0080 ..U+FFFF

    • 带引号的标识符中允许的字符包括完整的 Unicode 基本多语言平面 (BMP),但 U+0000 除外:

      • ASCII:U+0001 .. U+007F

      • 扩展:U+0080 ..U+FFFF

    [ deletia ]

    标识符引号字符是反引号(“`”):

    因此,要在 e-mail 列名中包含连字符(这通常是个坏主意),必须引用反引号中的标识符。

    【讨论】:

    • 从电子邮件中删除破折号取得了一些进展,我必须感谢您,但我现在收到此错误:i.imgur.com/1PvXtUV.png -- 我似乎找不到任何问题“用户名”的语法?
    猜你喜欢
    • 1970-01-01
    • 2018-03-14
    • 2018-07-23
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 2020-07-07
    • 1970-01-01
    相关资源
    最近更新 更多