4 Blueprints and Views| Flask开发

视图方法用来对发送给应用的request做出回应。

blueprint创建

使用blueprint组织一组相关的views及其他代码。将这些views及代码注册到blueprint而不是直接注册到应用。之后,blueprint被注册到应用中。
下面是创建blueprint的例子:
flaskr/blueprint_sample.py

import functools

# blueprint、数据处理、路由和模板渲染的包
from flask import (
    Blueprint, flash, g, redirect, render_template, request, session, url_for
)
# hash密码的生成和检验
from werkzeug.security import check_password_hash, generate_password_hash

from flaskr.db import get_db

# blueprint_name 是蓝图的名称
# target_directory 是视图函数(.py)文件存放的位置,如auth(用户的登录、注册、退出登录)、blog(博客的创建、修改、删除)等
bp = Blueprint('blueprint_name', __name__, url_prefix='/target_directory')

下面的代码把创建好的blueprint注册到factory function中:
flaskr/__init__.py

def create_app():
    app = ...
    # existing code omitted

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

    return app

The first view:register

下面是register view,从中可以看到处理用户注册以及flask(广义上)处理输入信息的方法。

@bp.route('/register', methods=('GET', 'POST'))
def register():
    if request.method == 'POST':
    	# 用request.form['<column_name>']从template获得表项
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        # 在base.html的content section里输出error message
        error = None
		
		# 下面可以用作error check的参考代码
		# 如果username为空;下同
        if not username:
            error = 'Username is required.'
        elif not password:
            error = 'Password is required.'
        elif db.execute(
            'SELECT id FROM user WHERE username = ?', (username,)
        ).fetchone() is not None:
            error = 'User {} is already registered.'.format(username)

        if error is None:
            db.execute(
                'INSERT INTO user (username, password) VALUES (?, ?)',
                (username, generate_password_hash(password))
            )
            # 如果查询语句修改了数据,则需要紧接着加上commit语句
            db.commit()
            # 转到登录view
            return redirect(url_for('auth.login'))
	
		# flash存储了可以在模板中渲染的信息
        flash(error)

	# 当用户第一次来到register页或者信息有error的时候,直接返回register页
    return render_template('auth/register.html')

fetchone() returns one row from the query. If the query returned no results, it returns None. Later, fetchall() is used, which returns a list of all results.

Login View

flaskr/auth.py

@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
            session.clear()
            session['user_id'] = user['id']
            # 重定向到合适的位置
            return redirect(url_for('index'))

        flash(error)

    return render_template('auth/login.html')

bp.before_app_request() registers a function that runs before the view function, no matter what URL is requested. load_logged_in_user checks if a user id is stored in the session and gets that user’s data from the database, storing it on g.user, which lasts for the length of the request. If there is no user id, or if the id doesn’t exist, g.user will be None.

flaskr/auth.py

@bp.before_app_request
def load_logged_in_user():
    user_id = session.get('user_id')

    if user_id is None:
        g.user = None
    else:
        g.user = get_db().execute(
            'SELECT * FROM user WHERE id = ?', (user_id,)
        ).fetchone()

Logout

To log out, you need to remove the user id from the session. Then load_logged_in_user won’t load a user on subsequent requests.
flaskr/auth.py

@bp.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('index'))

Require Authentication in Other Views

比较看不懂的地方。就先忽略啦。
Creating, editing, and deleting blog posts will require a user to be logged in. A decorator can be used to check this for each view it’s applied to.

flaskr/auth.py

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

This decorator returns a new view function that wraps the original view it’s applied to. The new function checks if a user is loaded and redirects to the login page otherwise. If a user is loaded the original view is called and continues normally. You’ll use this decorator when writing the blog views.

Endpoints and URLs

url_for()中的内容要做变化。从login变为auth.login。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值