liveBook · Manning

User model

As explained in The Well-Grounded Python Developer: How the pros use Python and Flask

A user model is a database-backed application model representing an account and its authentication-related attributes.

A login form needs a way to find the account behind an email address, while registration needs a place to save a new account. The User model handles both jobs: it represents an account in application storage and gives authentication code a common way to retrieve it. section 8.2.1 section 8.4

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 model is a SQLAlchemy table backed by a UserMixin class. Its fields include a generated UUID primary key, names, a unique indexed email address, a stored password hash, an active flag that defaults to false, and a creation timestamp. section 8.2.1

The login handler receives a submitted form and uses the model to find a matching account. Flask-Login also uses a user-loader function to retrieve a User by ID from a database session. Store password hashes rather than plain-text passwords; the application uses Flask-Bcrypt for hashing. Detailed SQLAlchemy and database treatment is deferred. section 8.2.1

One model, two account workflows

On registration, a submitted form becomes a new User saved to storage, after which the visitor goes to the login page. On login, the flow runs the other way: submitted credentials lead to a stored User, and a successful match takes the visitor to the home page or their original destination. section 8.4 section 8.2.1

How The Well-Grounded Python Developer: How the pros use Python and Flask covers it

How deep it goes
Shows a concrete table definition and authentication workflows, while deferring detailed SQLAlchemy and database instruction.
Examples
Uses a User table definition, a login user-loader, and contrasting login and registration workflows.
What it assumes
Assumes familiarity with Flask routes and forms, while deferring detailed database and SQLAlchemy instruction.
What you can do after
Build it from scratch as a SQLAlchemy account model used to save registrations and retrieve users for authentication.
How it connects
Connects the User model to registration, login forms, password hashing, database sessions, and Flask-Login user loading.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Python Developer: How the pros use Python and Flask. The section links point to the parts of the book it draws on.