flask基础2
Flask中send_file的使用
Flask中的send_file方法可以向浏览器中返回图片、音频与视频~对于浏览器未知格式的文件全部以下载的方式传送!
因此我们可以灵活的在某些视图函数中return一下send_file~~
比如说,用户输入一个未知的路由(浏览器默认返回404页面)可以给用户返回一个提示的图片或者视频音频文件~也可以自己定制一个404页面~
@app.errorhandler(404) def error404(error_message): print(error_message)
# 这个linux.mp4文件跟启动项目的py文件在一个目录
# 实际中需要用os.path去拼接文件的路径 return send_file("linux.mp4")
Flask中的路由
endpoint ***
endpoint是为flask的一个了路由作别名用的。
@app.route('/index/',endpoint='index') def index(): return render_template('index.html',stu_dic=STUDENT_DICT)
methods ***
methods表示当前的视图函数支持的请求方法。
注意:405表示请求方式不被允许——一般都是请求错了~将get请求与post请求换一下~
@app.route('/login',methods=['GET','POST']) def login(): if request.method == 'GET': return render_template('login.html') elif request.method == 'POST': xxx
url_for方法 ***
类似于django的反向解析reverse方法,需要导入才能使用:
from flask import Flask, render_template, request, redirect,session,url_for
下面是一个重定向的例子:
如果这个url带参数的话~url_path后面也可以加参数,比如像这样:
动态参数路由 ***
如果跟url_path结合的话,注意url_path要加关键字参数~
strict_slashes
strict_slashes=True 是否严格遵循路由匹配规则 "/"
默认是True
defaults
defaults = {"id":1} 默认参数
一旦默认参数存在 视图函数中必须有一个形参去接收 形参变量名必须与 defaults 中的一致
redirect_to
redirect_to = "/login" ~~永久重定向
301 308 不经过视图函数的~这两个都是永久重定向~至于什么时候是301什么时候是308~未可知~~
Flask中的初始化配置
初始化配置其实就是在实例化Flask对象的时候加一些关键字参数。
比如:
app = Flask(__name__,template_folder="templates",static_folder="statics",static_url_path="/statics")
template_folder ***
template_folder="templatess" # 更改模板存放目录 默认值是 templates
static_folder ***
static_folder="statics", # 静态文件存放路径,默认是static
static_url_path ***
static_url_path="/static" # 静态文件访问路径 - 默认是 "/"+static_folder(默认时候随着static_folder的值变化)
特别要注意 static_folder(1) 和 static_url_path(2) 之间的区别与关系:
一、解释
(1)是存放静态文件的目录的名字!(2)是用户访问资源的路径!
默认情况下:(2)随着(1)的变化而变化~~比如说,我把static_folder改成了whw_static,那么static_url_path就变成了 /whw_static
二、实例
目录结构如下:
后台代码如下:
# -*- coding:utf-8 -*- from flask import Flask,render_template app = Flask(__name__,static_folder='staticfiles',static_url_path='/statics') app.debug = True @app.route('/',endpoint='index') def index(): return render_template('index.html') if __name__ == '__main__': app.run('127.0.0.1','5678')
index页面如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <img src="/statics/1.jpg" alt=""> </body> </html>
这里:我把 static_folder 设置成了staticfiles,而 static_url_path 设置成了 /statics ~~img的src需要基于/static的url才能访问!!!
Flask中的Config对象配置
—— 配置文件十分重要!对接第三方插件应用的时候用得到!
——用第三方组件的话需要先写入配置文件中才能用!
——这里只列出几种比较常见的~
DEBUG
编码阶段 代码重启 日志输出级别很低 页面中会显示错误及错误代码
TESTING
测试阶段 日志输出级别较高 无限接近线上环境
SECRET_KEY
设置session的时候必须要用的~~
PERMANENT_SESSION_LIFETIME
session的生命周期,默认是31天——设置的话是按照秒为单位的~~
SESSION_COOKIE_NAME ***
必须记住这个~以后用第三方组件Flask-session的时候需要设置这个~~
JSONIFY_MIMETYPE ***
默认是 application/json ~~可以修改这个值来进行反爬~
快速切换Debug与测试环境 ***
实际中开发的Debug环境与测试环境不一样~需要用一种方法进行两者之间的灵活切换~
目录结构简单如下:
我在settings中写具体的配置,然后在s2这个文件中进行“切换”操作
settings.py文件的内容如下:
注意!每个类中的属性名必须大写
import hashlib class DebugSetting(object): DEBUG = True SECRET_KEY = hashlib.md5(b"12345!@#${}%^&*()_6789").hexdigest() SESSION_COOKIE_NAME = "I am just Session" NARUTO = "DSB" WHW = "NB" SESSION_TYPE = 'Redis' class TesingSetting(object): TESTING = True SECRET_KEY = "!@#$%^&*()" SESSION_COOKIE_NAME = "have a nice time"
s2.py文件的内容如下:
from flask import Flask, render_template, jsonify from setting import DebugSetting from setting import TesingSetting app = Flask(__name__,template_folder="templates",static_folder="statics",static_url_path="/statics")
# app.config.from_object方法——参数是settings中定义的类!!! app.config.from_object(DebugSetting)
# app.config.from_object(TesingSetting) @app.route("/") def index(): return jsonify({"k":1}) if __name__ == '__main__': print(app.config) app.run()
Flask中的蓝图
Flask中的蓝图类似于Django中的app应用~~
看下面的具体的例子~
项目的目录结构如下:
service中是一个个“蓝图”,f1.py文件用来注册使用蓝图
service中的文件内容~
car.py文件
# -*- coding:utf-8 -*- from flask import Blueprint #url_prefix为这个url加一个前缀~以后需要访问:/car/get_car才能得到视图函数get_car的结果 car = Blueprint("car",__name__,url_prefix="/car") @car.route("/get_car",methods=["GET","post"]) def get_car(): return "I am car Blueprint" @car.route("/set_car",methods=["GET","post"]) def set_car(): return "I am set car Blueprint"
users.py文件
# -*- coding:utf-8 -*- from flask import Blueprint #url_prefix为这个url加一个前缀 user = Blueprint("user",__name__,url_prefix="/ub") def look_your_LV(): print("ube") return "NONONO" def look_your_LV_gunc(res): print("uba") return res @user.route("/get_user",methods=["GET","post"]) def get_user(): return "I am Users Blueprint"
f1.py文件:
主文件用来年调用、注册并使用蓝图:~~注意引入的是实例化的对象~~
# -*- coding:utf-8 -*- from flask import Flask, redirect, send_file from service.users import user from service.car import car app = Flask(__name__) app.config["DEBUG"] = True if __name__ == '__main__': # 在主文件中注册蓝图~不用的话直接注释掉就好了 app.register_blueprint(user) app.register_blueprint(car) app.run('127.0.0.1',9002)
访问需要注意加上前缀:
前面设置前缀了~访问的时候需要加上前缀!
Flask中的特殊装饰器(请求扩展)
三个特殊的装饰器
@app.before_request
@app.after_request
@app.errorhandler
一个实例
# -*- coding:utf-8 -*- from flask import Flask, redirect, send_file from service.users import user from service.car import car app = Flask(__name__) app.config["DEBUG"] = True @app.before_request # 请求进入视图函数之前 def be1(): print("be1") # return "出错了" # 如果不return None表示异常~~不会执行视图函数 return None @app.before_request # 请求进入视图函数之前 def be2(): print("be2") return None @app.after_request def af1(res): print("af1") return res # 注意app.after_request装饰的函数必须返回res @app.after_request def af2(res): print("af2") return res # 自定制错误信息 @app.errorhandler(404) def error404(error_message): print(error_message) return send_file("static/1.png")
# 蓝图还是上面的 app.register_blueprint(user) app.register_blueprint(car) if __name__ == '__main__': app.run('127.0.0.1',9111)
前两个与视图函数有关的
如果需要大量的校验~可以像Django中间件那样在视图函数执行之前统一做一下校验~~
before_request
请求进入进入视图函数之前进行处理 return None 继续执行 否则阻断
按照函数定义的顺序从上到下顺序执行~~
after_request
视图函数结束 响应客户端之前
按照函数定义的顺序从下到上逆序执行~~
正常周期
be1 - be2 - be3 - vf - af3 - af2 - af1
异常周期
be1 - af3 - af2 - af1
也可以在蓝图中使用这两个装饰器
拿上面蓝图的例子来说,可以直接在users.py文件中加上装饰器:
# -*- coding:utf-8 -*- from flask import Blueprint #url_prefix为这个url加一个前缀 user = Blueprint("user",__name__,url_prefix="/ub") @user.before_request def look_your_LV(): print("ube") return "NONONO" @user.after_request def look_your_LV_gunc(res): print("uba") return res @user.route("/get_user",methods=["GET","post"]) def get_user(): return "I am Users Blueprint"
自定制错误页面的装饰器errorhandler
——不是很常用~但是能实现很棒的效果~
像上面的例子,如果遇到404页面未找到的错误,可以返回一个自己定制的信息:
# 自定制错误信息 @app.errorhandler(404) def error404(error_message): print(error_message) return send_file("static/1.png")
特别注意两点:
一、errorhandler只能监听错误的状态吗,也就是说这个“带参数的装饰器”里面的参数只能是 4xx与5xx系列的错误状态码
二、它所装饰的那个函数,必须有一个形参来接收error_massage这个值!