无法将WTForms数据提交到MySQL

时间:2014-02-19 07:31:18

标签: python mysql flask wtforms flask-wtforms

无法将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开发的新手。

2 个答案:

答案 0 :(得分:0)

正如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列名称中包含连字符(这通常是个坏主意),必须在反引号中引用标识符。

答案 1 :(得分:0)

您的代码存在两个问题。

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

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_usernameconfirm_passwordreg_email属性转换为字符串。您在错误消息中看到的值是TextField.__str__的返回值。

然后,您将enter_db作为Register的属性附加。 enter_dbUser实例化的,其值为Register.usernameRegister.passwordRegister.email。然后,仍然在课程创建时,您拨打Register.enter_db.database并为其指定与您用于实例Register.enter_db相同的值。

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

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

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

这使用字符串插值将usernamepasswordemail的值直接放入语句中,然后再执行它。除了这是一个不好的做法之外,其中一个值中的任何'都会破坏您的陈述。这就是你发生的事情,因为TextField.__str__包括字段名称周围的单引号。

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

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

然后,您将值传递给cur.execute

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

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