首页 > 解决方案 > hybrid_property 装饰器:无法设置属性错误

问题描述

我创建一个应用程序__init__.py如下:

from flask_bcrypt import Bcrypt

app = Flask(__name__, static_folder='static')
bcrypt = Bcrypt(app)

我在创建数据库模型时使用这个app实例,如下所示:

from sqlalchemy.ext.hybrid import hybrid_property
from app import bcrypt, db

class User(db.Model):

    name = db.Column(db.String, nullable=False)
    _password = db.Column(db.String)

    @hybrid_property
    def password(self) -> str:
        return self._password

    @password.setter
    def _set_password(self, password: str):
        self._password = bcrypt.generate_password_hash(password)

我尝试按如下方式启动一个实例(这是我想做的方式,因为它看起来更干净):

user = User(name='foo', password='bar')

但是当我将其提交到数据库时,我收到以下错误:AttributeError: can't set attribute。如果我使用,这将清除:

user = User(name='foo', _password='bar')

我想我没有@hybrid_property正确使用装饰器?如果可能,我想使用user = User(name='foo', password='bar')语法。

感谢您在这里的任何帮助。

标签: pythonsqlalchemydecoratorbcrypt

解决方案


无论您使用@hybrid_property装饰器还是原生 python 对象的@property装饰器,您都必须为 setter 或 getter 方法保留在属性定义中使用的相同属性名称。

在您的情况下, def_set_password()应该是def password(). 您的代码应如下所示:

 @hybrid_property
 def password(self):
     return self._password_hash

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

详细说明:https ://github.com/sqlalchemy/sqlalchemy/issues/4332


推荐阅读