Flask基础知识点1

一、.基于装饰器的session访问控制,endpoint路由参数可以解决视图函数重名的情况。

下面我有一个简单的需求,就是一个网站有三个页面,分别是home、index和login界面,用户只有当登陆后才可以正常访问home和index页面,通过装饰器的方法来实现。接下来看代码

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

app = Flask(__name__)
app.secret_key = "abcdefghijklmn"


def wrapper(f):
    def inner(*args, **kwargs):
        if session.get("user"):
            ret = f(*args, **kwargs)
            return ret
        else:
            return redirect("/login")

    return inner


@app.route("/login", methods=("GET","POST"))
def login():
    if request.method == "GET":
        return render_template("login.html")
    if request.method == "POST":
        username = request.form.get("username")
        session["user"] = username
        return "登陆成功"

@app.route("/home", methods=("GET", "POST"))
@wrapper
def home():
    return "这是home界面的内容"

@app.route("/index")
def index():
    return "我是index界面的内容"

app.run()

当我们只对home视图函数加上认证装饰器时实现了我们的需求,但是如果你给index也加上认证装饰器时你就会发现Flask项目启动不起来了,会报一个这样的错误:


image.png

这是因为,当我们对一个以上的视图函数添加了认证装饰器后 ,认证装饰器会将视图函数名替换成装饰器的内层函数名inner,在内存中就会出现视图函数名重复的情况,这样Flask的路由装饰器装饰视图函数时就会报错,解决这个错误的方法就是给路由的endpoint参数指定视图函数名,即:

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

app = Flask(__name__)
app.secret_key = "abcdefghijklmn"


def wrapper(f):
    def inner(*args, **kwargs):
        if session.get("user"):
            ret = f(*args, **kwargs)
            return ret
        else:
            return redirect("/login")

    return inner


@app.route("/login", methods=("GET","POST"))
def login():
    if request.method == "GET":
        return render_template("login.html")
    if request.method == "POST":
        username = request.form.get("username")
        session["user"] = username
        return "登陆成功"

@app.route("/home",endpoint="home", methods=("GET", "POST"))
@wrapper
def home():
    return "这是home界面的内容"

@app.route("/index",endpoint="index")
@wrapper
def index():
    return "我是index界面的内容"

app.run()

二、Flask中的路由参数

  • @app.route()
@app.route(
    "/<age>"                  // 动态路由参数,默认是string,也可以是"/<int:age>"
    redirect_to = "/login"    //不经过视图函数直接重定向指定url
    defaults = {"age": 999}   //指定默认参数
    endpoint = "home"         //路由别名,用于反向生成URL,即: url_for('名称')
    methods = ("GET", "POST") //请求方式
    strict_slashes = False    //是否严格匹配url最后的"/",例:http://127.0.0.1:5000/home 和 
                             //http://127.0.0.1:5000/home/
    )

常用动态路由参数有以下五种,所有的路由系统都是基于以下对应关系来处理:

DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}

url_for的用法

from flask import Flask,url_for

app = Flask(__name__)

@app.route("/index/<int:age>",endpoint="index")
def index(age):
    url = url_for("index",age = age)
    print(url)      //    "/index/122"
    return "我是index界面的内容"

app.run()
  • app.add_url_rule()方法:比@app.route()多了一个 view_func=view_func参数,其他的相同。

三、Flask配置文件

1. 初始化Flask实例时的配置

app = Flask(_name_,template_folder="template",static_folder="static",static_url_path="/static")

  • static_url_path = "/static_folder" 访问静态目录文件时的地址 默认值是等于static_folder的名字,(应用场景描述:当后端static文件名修改后,加入前端页面使用了大量的之前的static路径,可以将static_url_path参数设置为老的,这样就可以不用修改前端代码了。)
  • static_folder = "static" 静态文件的存放路径
  • template_folder='templates' 模板路径
2. Flask实例的配置 app配置
  • 方式一、app.config["DEBUG"] = True
    PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...)
  • 方式二、app.config.from_object(obj)
class obj():
    DEBUG = True
    SECERT_KEY = "123123"
  • 方式三、app.config.from_pyfile("settings.py")
    settings.py
DEBUG = True
SECERT_KEY = "123123"
  • 方式四、app.config.from_envvar("环境变量名称")
    PS:环境变量的值为python文件名称名称,内部调用from_pyfile方法
  • 方式五、app.config.from_json("json文件名称")
    PS: JSON文件名称,必须是json格式,因为内部会执行json.loads
  • 方式六、app.config.from_mapping({'DEBUG':True})
    PS:字典格式

四、Flask的蓝图

蓝图”和一个Flask应用对象很相似,但是并不是一个Flask应用对象。它是可以注册到Flask应用上的一系列操作(对于此的理解,后文会详细讲到)。使用“蓝图”,可以实现以下的一些功能:

  • 将Flask应用“分割”为一系列“蓝图”的集合,简化了大型应用工作的方式;
  • 在Flask应用上,以 URL 前缀和或子域名注册一个蓝图。可以以不同的URL多次注册一个蓝图;
  • 通过蓝图提供模板过滤器、静态文件、模板和其它功能。

第一步:蓝图的创建(蓝图的示例和Flask的实例参数一样)
add.py

from flask import Blueprint,render_template

bp = Blueprint("bp", __name__,
                   template_folder="blueprint_temp",
                   static_folder="blueprint_static",
                   static_url_path="/static2")

@bp.route("/add")
def add():
    return render_template("add.html")

第二步:注册蓝图:

from flask import  Flask
import add

app = Flask(\__name__)

app.register_blueprint(add.bp)

if __name__ == '__main__':
    app.run()

五、Flask里面的扩展,相当于django中的中间件

1.before_request 再请求进入视图函数之前作出处理 return None;before_request是顺序执行
2.after_request 在请求结束视图函数之后,返回客户端之前 ,要有参数和返回值,after_request是逆向执行
3.errorheadler(404) 自定制错误提示,自定义的函数必须有参数

  • before_request和after_request装饰器的使用
from flask import Flask, request, render_template, redirect, Markup, session, url_for

app = Flask(__name__)
app.secret_key = "abcdefghijklmn"


@app.before_request
def process_request1():
    print('process_request1')


@app.after_request
def process_response1(response):  # 必须有参数
    print('process_response1')
    return response  # 必须有返回值


@app.before_request
def process_request2():
    print('process_request2')


@app.after_request
def process_response2(response):  # 必须有参数
    print('process_response2')
    return response  # 必须有返回值


@app.route("/login", methods=("GET", "POST"))
def login():
    if request.method == "GET":
        return render_template("login.html")
    if request.method == "POST":
        username = request.form.get("username")
        session["user"] = username
        return "登陆成功"

app.run()

访问login视图函数后的控制台输出结果为:

process_request1
process_request2
process_response2
process_response1

通过代码的打印结果可以看出,before_request顺序执行;after_request逆向执行

  • errorhandler(404)的使用
@app.errorhandler(404)
def errors(code_or_exception):   //必须有参数
    return "错误"    //可以返回字符串,html,重定向等

六、闪现:flash

session存在在服务端的一个字典里面,session保存起来,取一次里面还是有的,直到你删除之后才没有了。

flash的本质:flash是基于session创建的,flash支持往里边放值,只要你取一下就没有了,相当于pop了一下。不仅吧值取走,而且吧session里的东西去掉。

flash的使用:get_flashed_messages()和flash("内容")

from flask import Flask,session,render_template,request,flash,get_flashed_messages
import flask_config

app = Flask(__name__) 

@app.route("/index")
def index():
    res = get_flashed_messages()
    if not res:
        res = [""]
    flash("你刚才访问了index")
    return render_template("index.html",msg=res[0])

@app.route("/home")
def index1():
    res = get_flashed_messages()
    if not res:
        res = [""]
    flash("你刚才访问了home")
    return render_template("index.html",msg=res[0])

if __name__ == '__main__':
    app.run()

七、Flask的send_file使用

from flask import Flask,send_file

app = Flask(__name__)

@app.route("/index", endpoint="index")
def index():
     return send_file(file_path)   //send_file()的作用是打开文件传输内容

app.run()

八、Flask的jsonify的使用

  • json.dumps的作用是序列化数据
  • jsonify的作用是将后端数据json序列化,打包一个 content-Type:application/json 返回给客户端
from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/index", endpoint="index")
def index():
     #return json.dumps({123:"34"})   //传给前端的是json数据,仅此而已!
     return jsonify({123:"34"}))    //序列化数据,将响应头的content-Type: 更改为application/json 
app.run()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容