Building Serverless Python Web Services with Zappa
上QQ阅读APP看书,第一时间看更新

Models

Let's start by creating the User model with basic functionality. The following is a code snippet of the user model.

File—auth/models.py:

import re
from datetime import datetime

from app.config.models import BaseModel
from flask_login.mixins import UserMixin
from sqlalchemy.orm import synonym
from werkzeug.security import generate_password_hash, check_password_hash
from app import db
from app import login_manager


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


def __init__(self, **kwargs):
super(User, self).__init__(**kwargs)

def __repr__(self):
return '<User {0}>'.format(self.email)

@property
def email(self):
return self._email

@email.setter
def email(self, email):
if not len(email) <= 64 or not bool(re.match(r'^\S+@\S+\.\S+$', email)):
raise ValueError('{} is not a valid email address'.format(email))
self._email = email

email = synonym('_email', descriptor=email)

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

@password.setter
def password(self, password):
if not bool(password):
raise ValueError('no password given')

hashed_password = generate_password_hash(password)
if not len(hashed_password) <= 128:
raise ValueError('not a valid password, hash is too long')
self.password_hash = hashed_password

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

def to_dict(self):
return {
'email': self.email
}


@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))

Now, we have created the User model, but how does it relate or map with the Flask-Login extension? The answer to this is the load_user method, which is wrapped by the login_manager.user_loader decorator. Flask provides this method to load the user into the session. This method is called with the user_id that's present in the session.

We can persist the user's data into the database with the help of the User model. As a web application, user data needs to enter through a user interface such as HTML. As per our requirements, we need two types of HTML forms for login and sign up functionality.

Let's move on to the next section and learn about rendering HTML forms through Flask.