• flask基础2


    一个装饰器无法装饰多个函数的解决方法

    当我们想在flask的多个视图函数前添加同一个装饰器时,如果什么都不做会报一个错

    AssertionError: View function mapping is overwriting an existing endpoint function: nei

    from flask import Flask, redirect, render_template, request, session
    
    app = Flask(__name__)
    app.secret_key = "12345"
    
    
    def wai(func):
        def nei(*args, **kwargs):
            if session.get("user"):
                ret = func(*args,**kwargs)
                return ret
            else:
                return redirect("/login")
        return nei
    
    
    @app.route("/")
    @wai
    def index():
        return render_template("index2.html")
    
    
    @app.route("/qqq")
    @wai
    def qqq():
        return render_template("qqq.html")
    
    
    @app.route("/login", methods=["POST", "GET"])
    def login():
        if request.method == "GET":
            return render_template("login.html")
        else:
            if request.form.get("username") == "12345" and request.form.get("password") == "12345":
                session["user"] = request.form.get("username")
                return "登录成功"
    
    
    app.run(debug=True)

      会报上面的错,原因是用装饰器去装饰函数时返回的是nei这个函数,也就是有两个nei函数,所以报错

    解决方案1

    import functools #引入一个函数工具
    
    def wai(func):
        @functools.wraps(func) #加上这句就会保留原来的函数名
        def nei(*args, **kwargs):
            if session.get("user"):
                ret = func(*args,**kwargs)
                return ret
            else:
                return redirect("/login")
        return nei

    解决方案2

    因为是flask视图函数,所以它为我们准备了一个参数endpoint 它反向生成url地址标志,默认视图函数名
    
    @app.route("/", endpoint="index")
    @app.route("/qqq", endpoint="qqq")

    1.flask中的路由

    1.endpoint 反向生成url地址标志 默认视图函数名 可以from flask import url_for url_for("")

    2.methods 视图函数允许的请求方式

    @app.route("/login", methods=["GET", "POST"]) #默认下面的函数只有get请求,一旦添加了methods参数就会按照添加的请求方式处理,后面是一个可迭代对象列表或元组

    3.动态路由参数

    @app.route("/login/<string:nid>", methods=["GET", "POST"], strict_slashes=False) #<string:nid>只有string或int类型,不写就是string 有动态路由参数下面的函数必须接受参数
    def index2(nid):
        print(url_for("index2"))
        print(nid)
        return "456"

    4.defaults={"nid":"123456"} 默认参数

    5.strict_slashes=True 是否严格遵循路由地址 不写就是false

    6.redirect_to="/login" 永久重定向 301   #进入视图之前

    2.flask实例化配置

    app = Flask(__name__, template_folder="templates", static_folder="static", static_url_path="/static")
    1.template_folder="temp" 默认模板路径 templates
    2.static_folder="static", 默认静态文件路径 static
    3.static_url_path="/static" 访问静态文件路由地址 默认是"/"+static_folder
    
    4.static_host=None 指定静态文件服务器地址
    5.host_matching = False,  # 如果不是特别需要的话,慎用,否则所有的route 都需要host=""的参数
    6.subdomain_matching = False,  # 理论上来说是用来限制SERVER_NAME子域名的,但是目前还没有感觉出来区别在哪里
    7.instance_path = None,  # 指向另一个Flask实例的路径
    8.instance_relative_config = False  # 是否加载另一个实例的配置
    9.root_path = None  # 主模块所在的目录的绝对路径,默认项目目录

    3.flask对象配置

    'DEBUG': False,  # 是否开启Debug模式
    'TESTING': False,  # 是否开启测试模式
    'SECRET_KEY': None # 在启用Flask内置Session的时候/开启flash,一定要有它
    'PERMANENT_SESSION_LIFETIME': 31,  # days , Session的生命周期(天)默认31天
    'SESSION_COOKIE_NAME': 'session',  # 在cookies中存放session加密字符串的名字
    #配置方式1
    app.config["DEBUG"] = True
    #配置方式2
    FlaskSetting.py
    --------------------------------------
    class FlaskDebug(object):
        DEBUG = True
        SECRET_KEY = "LIANNDA"
        PERMANENT_SESSION_LIFETIME = 7
        SESSION_COOKIE_NAME = "debug_session"
    
    class FlaskTesting(object):
        DEBUG = True
        SECRET_KEY = "LIANNDA"
        PERMANENT_SESSION_LIFETIME = 15
        SESSION_COOKIE_NAME = "test_session"
    ----------------------------------------------------------------
    

    import FlaskSetting app.config.from_object(FlaskSetting.FlaskDebug) app.config.from_object(FlaskSetting.FlaskTesting)

    4.flask蓝图(蓝图配置)

    Blueprint 当成一个不能被启动的 app Flask示例

    # 蓝图配置
    from flask import Blueprint, render_template
    
    s4app = Blueprint("s4app", __name__, template_folder="apptemp", url_prefix="/lantu")  #前三个参数必须给,后一个可选,如果添加了在访问时/lantu/s4app
    
    @s4app.route("/s4app")
    def s4appa():          # 蓝图实例名不要与函数名重复
        return render_template("s4app.html")  
    #在flask实例上注册蓝图,才能访问
    from user_reg import views
    app.register_blueprint(views.s4app)

    5.flask中的特殊装饰器

    @app.before_request # 请求进入视图函数之前

    @app.after_request # 响应返回客户端之前

    如果有多个before_request按从上到下执行,多个after_request按从下到上执行

    正常情况下流程:be1 - be2 - be3 - af3 - af2 - af1
    异常情况下流程:be1 - af3 - af2 - af1

    @app.before_request
    def be1():
        if request.path == "/login":
            return None
        if not session.get("user"):
            return redirect("/login")
    
    @app.after_request
    def af1(response):
        return response

    @app.errorhandler(404) # 重定义错误页面返回信息

    @app.errorhandler(404) #填错误码
    def error404(error):   #接收参数为错误信息
        return render_template("my_error.html") 
  • 相关阅读:
    Python cmd库的简易使用
    声明式编程与命令式编程
    javascript移除树形列表(带children的对象数组)中的元素
    javascript将树结构的列表转换为普通列表(不带children)
    javascript将普通列表转换为树结构的列表(带children)
    webservice的概述
    java程序员面试应该具备的一些基本技能
    mysql生成随机id
    struts2的优点
    javascript常用的正则表达式集合
  • 原文地址:https://www.cnblogs.com/qq849784670/p/10245023.html
Copyright © 2020-2023  润新知