zoukankan      html  css  js  c++  java
  • Flask系列之蓝图中使用动态URL前缀

    让我们先来看一个简单的例子,假设有下面这样一个蓝图(是关于用户主页的):

    from flask import Blueprint, render_template
    
    profile = Blueprint('profile', __name__)
    
    @profile.route('/<user_url_slug>')
    def timeline(user_url_slug):
        # Do some stuff
        return render_template('profile/timeline.html')
    
    @profile.route('/<user_url_slug>/photos')
    def photos(user_url_slug):
        # Do some stuff
        return render_template('profile/photos.html')
    
    @profile.route('/<user_url_slug>/about')
    def about(user_url_slug):
        # Do some stuff
        return render_template('profile/about.html')

    从上面我们可以看出,所有的路由都是以user_url_slug开头的,若这样写代码的话,会增加代码的复杂性、降低可维护性。为了解决这个问题,我们可以在蓝图中定义动态的URL前缀。让我们把蓝图定义改成这样:

    profile = Blueprint('profile', __name__, url_prefix='/<user_url_slug>')

    或者在注册到app时指定:

    app.register_blueprint(profile, url_prefix='/<user_url_slug>')

    现在,我们可以把路由写成下面的精简形式:

    @profile.url_value_preprocessor
    def pull_user_url_slug(endpoint, values):
        g.user_url_slug = values.pop('user_url_slug')
        query = User.query.filter_by(url_slug=g.user_url_slug)
        g.profile_owner = query.first_or_404()
    
    @profile.route('/')
    def timeline():
        return render_template('profile/timeline.html')
    
    @profile.route('/photos')
    def photos():
        return render_template('profile/photos.html')
    
    @profile.route('/about')
    def about():
        return render_template('profile/about.html')

    url_value_preprocessor装饰器用于把user_url_slug值弹出,并保存到g变量中,这样就不会传递给路由函数。

    实际应用中,我们会发现,若使用url_for来生成URL,会出现参数不足的错误,这是为什么呢?这是因为我们把user_url_slug弹出了,url_for工作时需要使用这个值,但是这个时候这个值找不到了,因此我们要把user_url_slug值重新压入:

    profile.url_defaults
    def add_user_url_slug(endpoint, values):
        values.setdefault('user_url_slug', g.user_url_slug)

    完整例子:

    from flask import Blueprint, render_template
    
    profile = Blueprint('profile', __name__, url_prefix='/<user_url_slug>')
    
    @profile.url_defaults
    def add_user_url_slug(endpoint, values):
        values.setdefault('user_url_slug', g.user_url_slug)
    
    @profile.url_value_preprocessor
    def pull_user_url_slug(endpoint, values):
        g.user_url_slug = values.pop('user_url_slug')
        query = User.query.filter_by(url_slug=g.user_url_slug)
        g.profile_owner = query.first_or_404()
    
    @profile.route('/')
    def timeline():
        return render_template('profile/timeline.html')
    
    @profile.route('/photos')
    def photos():
        return render_template('profile/photos.html')
    
    @profile.route('/about')
    def about():
        return render_template('profile/about.html')
  • 相关阅读:
    composer 中国全量镜像 laravel-china.org
    Increase PHP script execution time with Nginx
    How to make a USB stick use ISO image file in debian
    Getting svn to ignore files and directories
    Carbon document
    Use Laravel/homestead 环境维护基于 brophp 开发的老项目
    Vagrant WinNFSd
    How to use jQuery countdown plugin
    消息系统的设计与实现
    VMvare 复制的数据库,需要改变的配置
  • 原文地址:https://www.cnblogs.com/wangshuyang/p/8931755.html
Copyright © 2011-2022 走看看