Flask:路由、配置、蓝图、flash、特殊装饰器、CBV

flask 中的路由

1、路由中的一些简单的参数配置

  @app.router(  ........  )

1)endpoint          # 反向生成url地址标志 默认视图函数名 url_for 

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

3)"/index/<int:page>"   # 动态路由路由参数,也可以是<str:page>, 只有<page>默认是str,也可以接收数字类型

       def index(page)

              return             

4)strict_slashes=True         # 是否严格遵循自定义路由地址规则, xxx/index/1  (xxx/index/1/ 没有最后一个/)      

5)defaults={"nid":"123456"}   # 默认参数,此时视图函数要传参 nid,必须叫nid 

6)redirect_to="/login"        # 永久重定向 301,在进入视图函数之前重定向到/login

2、示例

from flask import Flask

app = Flask(__name__)


@app.route("/index/<int:page>", methods=["GET", "POST"], endpoint="index", defaults={'nid': "122"}, strict_slashes=True)
def index(page, nid):
    print(page, type(page))
    print(nid)
    return "123"


# http://127.0.0.1:5000/index/1/  不可以访问,不能有最后一个斜杠,要严格遵守规则 strict_slashes=True

@app.route("/", redirect_to="/login")
def index2():
    return "ok"


@app.route("/login", methods=["GET", "POST"])
def login():
    return "login"


if __name__ == '__main__':
    app.run("127.0.0.1", 5000, debug=True)

flask 的实例化配置

 1、实例化配置也就是给 Flask 实例化的时候的参数配置

  app = Flask(__name__,.............. )

1)template_folder="temp"      # 不指定参数,则默认模板路径 templates

2)static_folder="statics",     # 默认静态文件路径 static

3)static_url_path="/static"   # 访问静态文件路由地址 默认是"/"+static_folder,,通过访问 /static 找到 statics 文件夹

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             # 主模块所在的目录的绝对路径,默认项目目录

2、示例

from flask import Flask, render_template

app = Flask(__name__, template_folder="temp", static_folder="statics", static_url_path="/static")
                                                # 通过访问 /static  会找到 statics文件夹

@app.route('/')
def file():
    return send_file('static/22.png')     # 注意static这里前面不加/

@app.route("/login", methods=["GET", "POST"])
def login():
    return render_template("index.html")

if __name__ == '__main__':
    app.run("0.0.0.0", 5000, debug=True)

总结:

  1、在使用static_folder时,如果视图函数中不是该名称,需要在实例化中设置 static_url_path

  2、Flask实例化设置,主要是设置文件夹、路径等

flask 的对象配置

1、对象配置就是给实例化后的对象 app 添加配置

  直接用 app.xxxx     就可以添加配置

  app 对象的配置有很多,这里先简单介绍几种

'DEBUG': False,      # 是否开启Debug模式

'TESTING': False,    # 是否开启测试模式

'SECRET_KEY': None   # 在启用Flask内置Session的时候/开启flash,一定要有它

'PERMANENT_SESSION_LIFETIME': 31,  # days , Session的生命周期(天)默认31天

'SESSION_COOKIE_NAME': 'session',  # 在cookies中存放session加密字符串的名字

2、示例

  方式一:直接用 app.xxx 方式配置

from flask import Flask,session,redirect,request,render_template
from user_reg import views

app = Flask(__name__)


app.debug=True   # 不设置默认是false
# app.testing=True   # 不设置默认是false
app.secret_key = "#$%^&*"
app.secret_key="abhnhcd"   # 随便字符串
app.permanent_session_lifetime = 7   # session存储7天
app.session_cookie_name = "session"  # 在cookies中存放session加密字符串的名字

@app.route("/")
def index():
    return 'ok'

  方式二:使用类的方式进行对象配置

    app.config.from_object(    )

flaskapp 文件:

from flask import Flask,render_template,flash,get_flashed_messages
app = Flask(__name__)

import FlaskSetting
app.config.from_object(FlaskSetting.FlaskDebug)   # 导入debug中的一些配置
# app.config.from_object(FlaskSetting.FlaskTesting)  # 导入测试中的一些配置


@app.route("/")
def index():
    return "ok"


if __name__ == '__main__':
    app.run("0.0.0.0",5000)

FlaskSetting.py

class FlaskDebug(object):
    DEBUG=True
    SECRET_KEY="DEBUGmoshidesecret_key"
    PERMANENT_SESSION_LIFETIME = 7
    SESSION_COOKIE_NAME = "debug_session"

class FlaskTesting(object):
    TESTING=True
    SECRET_KEY="TESTINGmoshidesecret_key"
    PERMANENT_SESSION_LIFETIME = 15
    SESSION_COOKIE_NAME = "TESTING_session"

总结:

  1、app对象配置,主要配置 debug模式或 测试模式 ,session相关内容

flask 的蓝图

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

示例:

s4.py

from flask import Flask
from user_reg import views   # 导入蓝图所在的py文件

app = Flask(__name__)
app.register_blueprint(views.s4app, url_prefix="/user")    # 一定要注册蓝图,才能使用if __name__ == '__main__':
    app.run(debug=True)


'''
如果是在注册蓝图的时候 添加了前缀 url_prefix,以注册的为准,
也就是访问的时候:127.0.0.1:5000/user/index    直接忽略掉 /home就行了
'''

user_reg / views.py

from flask import Blueprint,render_template,send_file

s4app = Blueprint("s4app",__name__,template_folder="apptemp",url_prefix='/home')  # 这里的前缀最终以注册的为准,

@s4app.route("/index")
def index():
    # return render_template("s4app.html")    # 可以返回多个类型
    # return send_file('static/22.png')
    return '我是蓝图中的内容'

'''
url_prefix='home'  是url前缀,也就是访问的时候需要是:/home/index
通过访问 127.0.0.1:5000/home/index  便可以访问视图函数index
'''

总结:

  1、蓝图(Blueprint)的使用和Flask的使用是类似的,只是不能被启动

  2、注意url前缀 url_prefix 的使用,注册和实例化都添加的情况下,以注册的前缀为准

  3、一定要记得在 app Flask 中注册蓝图(register_blueprint)

flask 中的 flash(闪现)

闪现,就是存进去取出来

from flask import Flask, render_template, flash, get_flashed_messages

app = Flask(__name__)


@app.route("/index")
def index():
    # print(get_flashed_messages(category_filter="tag"))
    print(get_flashed_messages(category_filter=["tag1", ]))   # [闪现1]
    print(get_flashed_messages(category_filter=["tag", ]))    # []
    return "123"


@app.route("/login", methods=["GET", "POST"])
def login():
    flash("闪现", "tag")
    flash("闪现1", "tag1")
return render_template("index.html")


if __name__ == '__main__':
    app.run("0.0.0.0", 5000)

 总结:

  1、flash(消息,标签)  

    源码:def flash(message, category='message')

      参数1,message,是存放的内容;参数2,标签,是给内容添加标签,取值的时候可以通过标签取值,不写默认标签是消息内容

  2、flash 存值

    只能是一个一个的存入,存入多个值,需要写多次

  3、flash 取值

    当有多个内容和tag的时候,取其中的一个tag,那么,会得到列表中含有该tag对应的内容,

    但是其他tag中的内容也会被释放,再去取其他tag值,为空

flask 中的特殊装饰器(中间件)

特殊装饰器有3个,类似django中的中间件

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

@app.after_request          # 响应返回客户端之前执行
    正常情况下流程:be1 - be2 - be3 - af3 - af2 - af1
    异常情况下流程:be1 - af3 - af2 - af1    # 如果走到be1,之后出现异常,直接从响应返回 3 2 1

@app.errorhandler(404)     # 重定义错误页面返回信息
def error404(error_info):   # 必须接收一个参数,就是错误信息,
    return 三剑客+小儿子

总结:

  1、含有多个 @app.before_request、@app.after_request 时,

    正常情况下执行顺序是,before:自上而下,after:自下而上,be1 - be2 - be3 - af3 - af2 - af1

    如果中间be 有 return 内容的,be1 - af3 - af2 - af1    # 如果走到be1,之后出现异常,直接从响应返回 3 2 1

  2、django的request 和response是一一对应的关系,从哪里返回,就从哪个对象的response执行,

示例:

from flask import Flask
from flask import session, redirect, request, render_template

app = Flask(__name__)


@app.before_request  # 请进入视图函数之前,执行
def be1():
    print("我是 before_request1")
    if request.path == "/login":
        return None              # 返回None可以执行视图函数

    if not session.get("user"):
        return redirect("/login")   # 返回其他的内容就直接返回


@app.before_request    # 请进入视图函数之前
def be2():
    print("我是 before_request2")
    return render_template("error.html")      # 返回了一个页面,就不会再执行请求的视图函数了


@app.before_request  # 请进入视图函数之前
def be3():
    print("我是 before_request3")     # 没有return 会直接执行视图函数


@app.after_request  # 在响应客户端之前
def af1(args):
    print("我是 after_request1")
    return args


@app.after_request  # 在响应客户端之前
def af2(args):
    print("我是 after_request2")
    return args


@app.after_request  # 在响应客户端之前
def af3(args):
    print("我是 after_request3")
    return args


@app.route("/")
def index():
    print("我是视图函数")
    return "123"


@app.route("/login")
def login():
    session["user"] = "123456"
    return "登录成功"


@app.errorhandler(404)     # 重定义错误信息
def error404():
    return "你访问的页面已经被怪兽吃了"


if __name__ == '__main__':
    app.run(debug=True)
View Code

flask 中的 CBV

示例:

from flask import Flask,render_template
from flask import views
app = Flask(__name__)


class Login(views.MethodView):

    def get(self):
        return render_template('login.html')

    def post(self):
        return '登陆成功'

app.add_url_rule('/login',view_func=Login.as_view('my_login'),methods=['GET','POST'])   # methods 不写也可以# methods 不写则任何请求只要有函数就能走,如果写了,就只能走列表中的请求,没有的即使有视图函数也不能走

app.run(debug=True)

 

总结:

  1、类一定要继承 views.MethodView

  2、通过 add_url_rule(  ) 来设置路由地址,视图函数等

    1)view_func = Login.as_view( "my_login")    通过 as_view() 入口,必须传递参数 视图函数名(自己定义即可),如果没有定义的话,最后as_view() 返回的都是 view,那么会重名,endpoint就会出错。

    2)methods = [  ]     可写可不写,methods 不写则任何请求只要有函数就能走,如果写了,就只能走列表中的请求,没有的即使有视图函数也不能走

  3、可以分析下源码,值得一看

 

posted @ 2019-01-08 21:42  葡萄想柠檬  Views(175)  Comments(0)    收藏  举报
目录代码