Flask-sqlalchemy:不能将属性字段作为关键字参数赋予构造函数

时间:2014-07-15 13:41:27

标签: python flask flask-sqlalchemy

我正在阅读“Flask Web Development”一书,并创建了一个类似于flasky(https://github.com/miguelgrinberg/flasky)的应用程序。我已经设置了用户模型:

from flask_login import UserMixin
from werkzeug.security import check_password_hash, generate_password_hash

from app import db


class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)
    password_hash = db.Column(db.String)

    @property
    def password(self):
        raise AttributeError('password is read-only')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return verify_password_hash(self.password_hash, password)

    def __init__(self, username, email):
        self.username = username
        self.email = email

现在在注册视图中我做了:

user = User(email=form.email.data, username=form.username.data,
                password = form.password.data)

我收到以下错误:

TypeError: __init__() got an unexpected keyword argument 'password'

奇怪的是,教程项目也是如此,见第54行https://github.com/miguelgrinberg/flasky/blob/master/app/auth/views.py

当我这样做时它起作用:

user = User(email=form.email.data, username=form.username.data)
user.password = form.password.data

但我希望能够将密码传递给构造函数。显然,flask_sqlalchemy不明白密码是属性。但是为什么这个在教程中有效呢?我找不到差异。

1 个答案:

答案 0 :(得分:3)

您覆盖__init__但不允许输入密码:

def __init__(self, username, email):
    self.username = username
    self.email = email

没有必要覆盖__init__,因为默认的SQLAlchemy模型提供了一个已接受所有字段的模型。只需删除__init__声明即可正常工作

code from the book Michael 覆盖__init__方法,但他接受所有关键字参数,他所做的第一件事就是将它们转发到超级构造函数(到保留SQLAlchemy的默认行为。)