简体   繁体   中英

The hybrid_property decorator: can't set attribute error

I create an app in __init__.py as follows:

from flask_bcrypt import Bcrypt

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

and I use this app instance when creating database models as follows:

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)

And I try to initiate an instance as follows (this is the way that I want to do it as it looks cleaner):

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

but when I commit this to a database I get the following error: AttributeError: can't set attribute . This clears if I use:

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

I guess I'm not using the @hybrid_property decorator properly? I want to use the user = User(name='foo', password='bar') syntax if possible.

Thanks for any help here.

Whether you use @hybrid_property decorator or a native python object's @property decorator you must retain same attribute name used in property definition for setter or getter methods.

Here in your case def _set_password() should be def password() . Your code should look like this:

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

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

Detail Explanation: https://github.com/sqlalchemy/sqlalchemy/issues/4332

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM