为了账号安全,请及时绑定邮箱和手机立即绑定

Presto 数据查询项目之项目框架用户管理模块

标签:
Python 大数据

经过前面的介绍,大家对于Flask的第三方模块应该是有一定的认识了。我们本文会用到Flask的表单模块和登录认证模块。要想实现用户的管理模块我们首先要开发我们的User Model。

from datetime import datetime
from flask import current_app
from flask_login import UserMixin
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from werkzeug.security import generate_password_hash, check_password_hash
from .. import db, login_manager
from ..core.basemodel import Serializable

# 开发USER model,及其相关字段
class User(UserMixin, db.Model):
    # 指定数据库中的表名
    __tablename__ = 't_user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64),
                         nullable=False, unique=True, index=True)
    password_hash = db.Column(db.String(128))
    create_time = db.Column(db.DateTime, default=datetime.now)

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

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

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

    def get_api_token(self, expiration=300):
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'user': self.id}).decode('utf-8')

    @staticmethod
    def validate_api_token(token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except:
            return None
        id = data.get('user')
        if id:
            return User.query.get(id)
        return None


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

开发完User Model之后,我们通过Flask WTF开发User登录的表单信息

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, ValidationError
from wtforms.validators import DataRequired, Length
from .models import User

# 登录表单
class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=4, max=16)])
    password = PasswordField('Password', validators=[DataRequired(), Length(min=6, max=16)])
    remember_me = BooleanField('Remember Me')
    submit = SubmitField(label=u'Login')

    def validate_username(self, field):
        if not self.get_user():
            raise ValidationError('Invalid username!')

    def validate_password(self, field):
        if not self.get_user():
            return
        if not self.get_user().check_password(field.data):
            raise ValidationError('Incorrect password!')

    def get_user(self):
        return User.query.filter_by(username=self.username.data).first()

# 注册表单
class RegisterForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(4, 16)])
    password = PasswordField('Password', validators=[DataRequired(), Length(6, 16)])
    password_confirm = PasswordField('ConfirmPassword', validators=[DataRequired(), Length(6, 16)])
    submit = SubmitField(label=u'Submit')

最后我们开发对应的Web接口,来实现我们的用户注册、登录、登出功能。

from flask import request, render_template, redirect, url_for
from flask_login import login_user, logout_user, login_required

from app import db
from .models import User
from . import auth
from .forms import LoginForm, RegisterForm
from ..core import baseapi


@auth.route('/auth/login', methods=['GET', 'POST'])
def login():
    user_data = request.form
    form = LoginForm(data=user_data)
    if request.method == 'POST' and form.validate():
        user = form.get_user()
        login_user(user, remember=form.remember_me.data)
        return redirect(url_for('query.index'))
    return render_template('login.html', form=form, error=form.errors)


@auth.route('/auth/register', methods=['GET', 'POST'])
def register():
    user_data = request.form
    form = RegisterForm(data=user_data)
    if request.method == 'POST' and form.validate():
        user = User(username=form.username.data, password=form.password.data)
        db.session.add(user)
        db.session.commit()
        return redirect(url_for('auth.login'))
    return render_template('register.html', form=form, error=form.errors)


@auth.route('/auth/logout', methods=['GET'])
@login_required
def logout():
    logout_user()
    return redirect(url_for('auth.login'))

现在我们的auth模块已经开发完了,我们知道在Flask中使用蓝图对应用进行模块化,我们的auth模块也是这样。我们先来简单介绍一下蓝图。Flask中的蓝图就是Blueprint,它是简化大型应用并为扩展提供集中的注册入口。在蓝图被注册到应用之后,所要执行的操作的集合。当分配请求 时, Flask 会把蓝图和视图函数关联起来,并生成两个端点之前的 URL 。我们来看一个简单的示例,以我们的auth模块为例:

init.py
from flask import Blueprint

auth = Blueprint('auth',__name__)
from . import views
app init.py
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from config import config
from flask_bootstrap import Bootstrap

# 初始化db及login_manager模块
db = SQLAlchemy()
login_manager = LoginManager()
login_manager.login_view = 'auth.login'

config_name = os.getenv('FLASK_CONFIG') or 'default'
# 初始化Flask实例
app = Flask(__name__)
app.config.from_object(config[config_name])

config[config_name].init_app(app)
# 对第三方扩展进行初始化
db.init_app(app)
login_manager.init_app(app)
bootstrap = Bootstrap(app)
app_config = app.config

# 注册蓝图
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)

from .queryserver import query as query_blueprint
app.register_blueprint(query_blueprint)

with app.app_context():
    db.create_all()
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
1.1万
获赞与收藏
510

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消