• flask的url处理器(url_defaults和url_value_preprocessor)


    • url处理器的作用:对于一部分资源, 你并不是很清楚该如何设定其 URL 相同的部分。例如可能有一些URL包含了几个字母来指定的多国语言语种,但是你不想在每个函数里都手动识别到底是哪个语言
    rom flask import Flask, g
    
    app = Flask(__name__)
    
    @app.route('/<lang_code>/')
    def index(lang_code):
        g.lang_code = lang_code    #你必须在每个函数当中手动处理g对象,这可能会产生一大片重复的代码
        ...
    
    @app.route('/<lang_code>/about')
    def about(lang_code):
        g.lang_code = lang_code    # 重复代码
        ...
    
    • url_value_preprocessor() 。该方法在请求(request)匹配成功立马执行,执行的代码基于URL传递的values。实际上,他们将信息从包含这些值的字典当中取出,然后将其放在某个其他的地方

      @app.url_value_preprocessor
      def pull_lang_code(endpoint, values):
          g.lang_code = values.pop('lang_code', None)
      
    • 简化后的代码如下:

    from flask import Flask, g
    
    app = Flask(__name__)
    
    @app.url_value_preprocessor
    def pull_lang_code(endpoint, values):   
      '''
      在处理第一次有lang_code参数的请求的时候,把g.lang_code设为用户需要的语言,后续的函数则不需要编写重复的代码了
      '''
        g.lang_code = values.pop('lang_code', None)
    
    @app.route('/<lang_code>/')
    def index():
        ...
    
    @app.route('/<lang_code>/about')
    def about():
        ...
    
    • 这样,您再也不必在每个函数中都要将 lang_code 分配给 g 了。 一旦lang_code被从字典里弹出,他就不会在被传递到视图函数当中。

    • 但是,若使url_for来生成URL,会出现参数不足的错误,这是因为pull_lang_codelang_code弹出了,url_for工作时需要使用这个值,但是这个时候这个值找不到了,因此我们要把lang_code值重新压入

    • 使用url_defaults装饰器的函数可以自动地将值注入到url_for()的调用中去

      @app.url_defaults
      def add_language_code(endpoint, values):  # 将lang_code值重新压入
          if 'lang_code' in values or not g.lang_code:
              return
          if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
              values['lang_code'] = g.lang_code
              
      @app.route('/<lang_code>/')
      def index(lang_code):
          pass
      
       url_for("index",lang_code='Zh')  
      # 此时会调用add_language_code(endpoint, values)函数
      # endpoint就是函数名index
      # values是包括url_for函数所有后面参数的dict,添加values的值,用于生成url
      
    • is_endpoint_expecting()用于找出往endpoint函数传递该参数是否有意义,在这个例子中,就是用来测试index函数是否需要’lang_code’这个参数

    • 综上,整体代码就可简化为如下形式:

      from flask import Flask, g
      
      app = Flask(__name__)
      
      @app.url_defaults      
      def add_language_code(endpoint, values):
          if 'lang_code' in values or not g.lang_code:
              return
          if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
              values['lang_code'] = g.lang_code
      
      @app.url_value_preprocessor
      def pull_lang_code(endpoint, values):   
          g.lang_code = values.pop('lang_code', None)
      
      @app.route('/<lang_code>/')
      def index():
          ...
      
      @app.route('/<lang_code>/about')
      def about():
          ...
      
    • 因为 Blueprint 能够自动地为所有 URL 添加一个相同的字符串作为前缀,所以自动处理这些函数变得非常简单。 每个蓝图都可以有一个 URL 处理器,因为不必检查lang_code参数,所以url_defaults可以简化为如下所示:

      from flask import Blueprint, g
      
      bp = Blueprint('frontend', __name__, url_prefix='/<lang_code>')
      
      @bp.url_defaults
      def add_language_code(endpoint, values):
          values.setdefault('lang_code', g.lang_code)
      
      @bp.url_value_preprocessor
      def pull_lang_code(endpoint, values):
          g.lang_code = values.pop('lang_code')
      
      @bp.route('/')
      def index():
          ...
      
      @bp.route('/about')
      def about():
          ...
      
  • 相关阅读:
    log4j(四)——如何控制不同风格的日志信息的输出?
    log4j(三)——如何控制不同级别的日志信息的输出?
    log4j(二)——如何控制日志信息的输出?
    【完全开源】知乎日报UWP版:增加Live磁贴、Badge、以及Toast通知
    【完全开源】知乎日报UWP版:项目结构说明、关键源代码解释
    【完全开源】知乎日报UWP版(下篇):商店APP、github源码、功能说明。Windows APP 良心出品。
    UWP开发:APP之间的数据交互(以微信为例)
    【完全开源】知乎日报UWP版(上篇):界面设计、官方API分析
    【完全开源】博客园客户端UWP版 带源码、带APP(下篇)
    UWP开发之控件:用WebView做聊天框
  • 原文地址:https://www.cnblogs.com/iamluoli/p/11202234.html
Copyright © 2020-2023  润新知