【问题标题】:flask wtforms_alchemy object has no attributeflask wtforms_alchemy 对象没有属性
【发布时间】:2015-04-14 01:26:11
【问题描述】:

我刚开始做flask restful api并尝试通过向localhost:5000/api/v1/users发送POST请求来注册用户。必填字段是电子邮件和密码。这是创建用户curl http://localhost:5000/api/v1/users -d "email=admin@example.com&password=password" -X POST -v的curl请求

但它返回给我这个错误:AttributeError: 'UserCreateForm' object has no attribute 'password'

下面是我的代码片段

views.py

class UserView(restful.Resource):
    def post(self):
        form = UserCreateForm()
        if not form.validate_on_submit():
            return form.errors, 422

        user = User(email=form.email.data, password=form.password.data)
        db.session.add(user)
        db.session.commit()
        return UserSerializer(user).data

forms.py

BaseModelForm = model_form_factory(Form)

class ModelForm(BaseModelForm):
    @classmethod
    def get_session(self):
        return db.session

class UserCreateForm(ModelForm):
    class Meta:
        model = User

models.py(我厌倦了将UserMixin 放在第二位,仍然出现同样的错误)

class User(db.Model, UserMixin):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    password_hash = db.Column(db.String(128))

    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')

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

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

另外,我有login_manager.user_loader,所以我认为烧瓶登录不会有问题。

有没有 wtform_alchemy 的文档?我完全不明白从模型自动创建表单的工作原理。

【问题讨论】:

    标签: flask flask-sqlalchemy flask-wtforms flask-login flask-restful


    【解决方案1】:

    UserCreateForm 将从您在User 上定义的列继承其字段。 User 没有名为 password 的列,因此 UserCreateForm 没有这样的字段。您必须自己添加该字段。

    from wtforms.fields import PasswordField
    
    class UserCreateForm(ModelForm):
        class Meta:
            model = User
    
        password = PasswordField()
    

    WTForms-Alchemy docs 谈论添加和覆盖字段。

    【讨论】:

    • 如果我想要不同的名称,例如数据库列中的fname,我想在表单中添加字段firstname。如果我执行firstname = TextField(),该字段的值是否会传递到我数据库中的fname 列?
    • 没有你告诉它。 WTForms-Alchemy 只能在名称匹配时建立连接。如果您需要进行任何自定义映射,则需要自己包含该映射。理想情况下,您不会在模型中给它一个名称,而在表单中给它另一个名称。但在密码的情况下,您可以实现自己的populate_obj 并包含obj.password = self.password.data 或类似的东西。
    • 密码现在有效,但我很好奇如何。您在表单字段中有password,但在db 列中它是password_hash,并且没有您提到的映射。
    • 之所以有效,是因为User 有一个名为password 的属性(但不是Column)。如果没有,您需要添加一些内容以将值分配给 password_hash
    • 在 cmets 中很难回答问题。如果您的原始问题已得到解决,请考虑接受此答案并提出新问题以获得正确答案。
    猜你喜欢
    • 1970-01-01
    • 2014-11-11
    • 2020-01-02
    • 2016-08-24
    • 2018-12-23
    • 2020-04-05
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多