A database-backed user needs to do two jobs: store account data and work with the login system. A Flask `User` class can inherit from both `UserMixin` and `db.Model`. `UserMixin` supplies methods expected by Flask-Login’s `LoginManager`; `db.Model` supplies the SQLAlchemy functionality for defining and accessing the user table. section 8.2.1
class User(UserMixin, db.Model): #1
__tablename__ = "user" #2
user_uid = db.Column(db.String, primary_key=True, default=get_uuid) #3
first_name = db.Column(db.String, nullable=False) #4
last_name = db.Column(db.String, nullable=False) #4
email = db.Column(db.String, nullable=False, #4
unique=True, index=True) #4
hashed_password = db.Column("password", #4
db.String, nullable=False) #4
active = db.Column(db.Boolean, nullable=False, default=False) #4
created = db.Column(db.DateTime, nullable=False, #5
default=datetime.utcnow) #5
updated = db.Column(db.DateTime, nullable=False, #5
default=datetime.utcnow, onupdate=datetime.utcnow) #5
def get_id(self):
return self.user_uid
@property
def password(self):
raise AttributeError("user password can’t be read")
@password.setter
def password(self, password):
self.hashed_password = generate_password_hash(password)
def verify_password(self, password):
return check_password_hash(self.hashed_password, password)
def __repr__(self):
return f"""
user_uid: {self.user_uid}
name: {self.first_name} {self.last_name}
email: {self.email}
active: {'True' if self.active else 'False'}
"""
The `User` model inherits from both classes and defines account fields, including a UUID primary key named `user_uid`. section 8.2.1
Check the identifier before relying on the mixin unchanged. Its default `get_id()` uses `self.id`, but this model names its unique identifier `user_uid`. Override `get_id()` to use that field so the login system can identify the user. section 8.2.1
