前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flask的Blueprints和Views

Flask的Blueprints和Views

作者头像
dongfanger
发布2021-11-30 21:55:13
6650
发布2021-11-30 21:55:13
举报
文章被收录于专栏:dongfangerdongfanger

Flask的view函数是用来对请求作出响应的。单个URL能匹配到单个View,那么多个类似的URL,比如:

代码语言:javascript
复制
/auth/register
/auth/login
/auth/logout

有没有什么比较优雅的写法呢?

Blueprints

Blueprints就是一个路由分组,可以把共同的路由前缀注册为一个Blueprint,比如:

flaskr/auth.py文件中先定义一个Blueprint:

代码语言:javascript
复制
import functools

from flask import (
    Blueprint, flash, g, redirect, render_template, request, session, url_for
)
from werkzeug.security import check_password_hash, generate_password_hash

from flaskr.db import get_db

bp = Blueprint('auth', __name__, url_prefix='/auth')
  • 'auth'是Blueprint的名字。
  • __name__用来告诉Blueprint它的定义位置。
  • url_prefix就是路由前缀。

接着在flaskr/__init__.py文件中注册:

代码语言:javascript
复制
def create_app():
    app = ...
    # existing code omitted

    from . import auth
    app.register_blueprint(auth.bp)

    return app

Views

定义和注册了Blueprints后就可以在view中使用了。比如:

①在flaskr/auth.py文件中添加一个注册view:

代码语言:javascript
复制
@bp.route('/register', methods=('GET', 'POST'))
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        error = None

        if not username:
            error = 'Username is required.'
        elif not password:
            error = 'Password is required.'

        if error is None:
            try:
                db.execute(
                    "INSERT INTO user (username, password) VALUES (?, ?)",
                    (username, generate_password_hash(password)),
                )
                db.commit()
            except db.IntegrityError:
                error = f"User {username} is already registered."
            else:
                return redirect(url_for("auth.login"))

        flash(error)

    return render_template('auth/register.html')
  • @bp.route就会把路由前缀加到'/register'上拼成/auth/register
  • request.form是一个字典,可以读取接口入参。
  • db.execute执行SQL语句。db.commit()提交。
  • redirect在注册成功后重定向到登录页面。
  • url_for根据view名字来获取url,因为这里用到了Blueprint,所以入参是"auth.login"。如果没有用Blueprint,url_for()函数入参就写view函数名即可。

②在flaskr/auth.py文件中添加一个登录view:

代码语言:javascript
复制
@bp.route('/login', methods=('GET', 'POST'))
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        error = None
        user = db.execute(
            'SELECT * FROM user WHERE username = ?', (username,)
        ).fetchone()

        if user is None:
            error = 'Incorrect username.'
        elif not check_password_hash(user['password'], password):
            error = 'Incorrect password.'

        if error is None:
            session.clear()
            session['user_id'] = user['id']
            return redirect(url_for('index'))

        flash(error)

    return render_template('auth/login.html')

③在flaskr/auth.py文件中添加一个登出view:

代码语言:javascript
复制
flaskr/auth.py
@bp.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('index'))
  • session.clear()清除session。

④最后可以在在flaskr/auth.py文件中顺手写一个装饰器,用来做认证鉴权:

代码语言:javascript
复制
def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if g.user is None:
            return redirect(url_for('auth.login'))

        return view(**kwargs)

    return wrapped_view

在需要登录才能访问的view上,就可以加上这个login_required装饰器。

参考资料: https://flask.palletsprojects.com/en/2.0.x/tutorial/views/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-11-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Blueprints
  • Views
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档