flask 复习

 

目录

一   小demo

二 杂乱的小知识

 1  不用装饰器绑定路由和函数

2 abort 函数, 立即终止对视图的访问

3 markup 渲染后端html到前端

4. 自定义宏

5 闪现  只有第一次访问才能拿到值

6 reques的参数

7 response的参数

8 上下文

三 路由

1.url_for 反向解析

2 加参数

3 其他的参数

4 子域名

四 flask的返回值

五 中间件和各种装饰器

1)用装饰器自定义局部中间件

2) 自定义全局中间件

3)自带的全局中间件before_request

4) after_request

5)before_first_request

6)errorhander()

7) template_global()

8) template_filter()

六 flask 的CBV

七 url 自定义正则

八 蓝图

九 上下文管理

十 flask 上传文件

十一 jinja模板

十二  flask多APP应用


一   小demo

app.py

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

app = Flask(__name__)
app.secret_key = 'xxx'     # 用session必须加
print(app.config)
# app.config['DEBUG'] = True
# 还可以自己写个settings文件,导入配置
# app.config.from_object("settings.Foo")


@app.route('/', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('xx.html')
    user = request.form.get('user')
    pwd = request.form.get('pwd')
    if user == 'xx' and pwd == 'xx':
        session['user'] = user
        return redirect('/index/')
    return render_template('xx.html', error='卧槽')
    # render_template('xx.html', **{"error": "xx})
    # 在前端直接渲染错误信息  {{ error }}

@app.route('/index/')
def index():
    user = session.get('user')
    if not user:
        return redirect('/login/')
    render_template('index.html')


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

settings.py

class Foo:
    DEBUG = False
    TEST = True

 

二 杂乱的小知识

 1  不用装饰器绑定路由和函数

app.add_url_rule('/'. 'index', index)
三个参数分别为 路由, 反向名, 函数

2 abort 函数, 立即终止对视图的访问

abort 函数, 立即终止对视图的访问,返回错误信息

from flask import Flask, abort

@app.route('/')
def get_user(id):
    user = load_user(id)
    if not user:
        abort(404)
    return xxxxx

 

3 markup 渲染后端html到前端

from flask import Flask, makeup

@app.route('/xx')
def xx():
    content = {
        'txt': makeup("")              
              }
     return render_template('xx.html', **content)
   

4. 自定义宏

{% macro ccc(name, type="text", value='') %}
自定义宏什么都显示

{% endmacro %}


正式调用宏,显示一个input 框
{{ ccc('n1','', 'xx') }}



一般会把宏写在一个单独的文件里
当宏作为一个单独文件时{% include 'xx' %}  要先引用

5 闪现  只有第一次访问才能拿到值

相当于用seesion存数据, 只能拿到一次里面的数据, 再拿就拿不到了

from flask import Flask, flash, get_flashed_messages

@app.route('/xxx')
def a():
    flash('xx')     # 相当于设置个seesion
    flash('xx', 'eeror')      # 相当于价格分类
    ......
 
@app.route('/xx')
def b():
    print(get_falshed_messages)
    print(get_flashed_messages(category_filter=['error']))

6 reques的参数

  • request.form                    相当于request.post
  • request.args                    相当于request.get
  • request.values                 form和args合集字典
  • request.header                字典, HTTP的首部
  • request.cookie                 字典, cookie
  • request.fiels                     字典, 文件
  • request.get_date()           返回主体缓存数据
  • request.get_json()            字典, Json格式请求体
  • request.endpoint              反向的name
  • request.method
  • request.blueprint
  • request.scheme              url方案???
  • request.is_secure           是不是安全连接(Https)
  • request.host                    主机名
  • request.path                    路径部分
  • request.query_string       url参数部, 二进制值
  • request.full_path             path+query_string
  • request.url                       完整的url
  • request.base_url              等价于path
  • request.remote_addr       IP地址
  • request.environ                请求原始的WSGIZ字典

7 response的参数

from flask import make_response

@app.route('/')
def index():
    response = make_response('xx')
    response.set_cookie('answer', '22')
    return response
  • response.status_code              设置Http状态码
  • response.headers                     类似字典, 包含发送的首部
  • response.set_cookie                 给响应加一个cookie
  • response.delete_cookie            删除一个cookie
  • response.content_length           响应主体的长度
  • response.content_type              响应主体的媒体类型
  • response.set_data()                   使用字符串或字节值设定响应
  • response.get_data()                   获取响应主体

8 上下文

https://blog.csdn.net/DeskyAki/article/details/89648260

三 路由

1.url_for 反向解析

endpoint相当于django的name, 就是反向解析的名字,flask不写endpoint反向解析的名字默认就是函数名,

url_for 反向解析额url, _external=True 返回绝对地址

from flask import Flask, url_for
@app.route('/index/', methods=['GET', 'POST'], endpoint='n1')
def index():
    print(url_for('n1'))
    # 打印结果 /index
    # print(url_for('n1', _external=True))
    # 返回绝对地址
    return "index"

url_for也可以匹配静态文件

 

2 加参数

@app.route('/index/')       # 形如/index/2
@app.route('/index/')           # 不写默认时字符串
@app.route('/index/')     # 浮点类型
@app.route('/index/')     # path
@app.route('/index/', method=["GET", "POST"])
def index(nid):
     print(url_for("index", nid=999))
     # 生成/index/999

关于path, 匹配/

@app.route('/center/')

访问/center/1/1
匹配到的uid 是1/1

3 其他的参数

@app.route('/index', strict_slashes=False)
# 不严格要求路由, /index/, /index


@qpp.route('/index', strict_slahes=True) 
# 严格要求url

@app.route('/index', redirect_to='xx')
# 重定向, 跳转到指定网址

4 子域名

要修改本地的host文件, 完成DNS解析

app = Flask(import_name = __name__)
app.config['SERVER_NAME'] = 'xxx.com:5000'
@app.route("/", subdomain='admin')
def adnm_index():
    return ...

http://admin.xxx.com:5000/

 

四 flask的返回值

from flask import Flask, jsonify, make_response

  1. return "字符串"
  2. return render_template()                              返回模板
  3. return redirect()                                             重定向
  4. dic =  {"k1": "v1"}        return jsonify(dic)       序列化
  5. 加响应头和cookie
    obj = make_response("index")
    obj.headers['xxxxx'] = '123'
    obj.set_cookie('key', 'value')         # 加session
    return obj

     

五 中间件和各种装饰器

中间件详情请看 https://blog.csdn.net/DeskyAki/article/details/97023979

1)用装饰器自定义局部中间件

from functools import wraps


def auth(func):
    @wraps(func)
    def inner(*args, **kwargs):
        if not session.get('user'):
            return redirect(url_for('login'))
        ret = func(*args, **kwargs)
        return ret
    return inner

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

2) 自定义全局中间件

写在app.py中

class Middleware(object):
    
    def __init__(self, old):
        self.old = old
    
    def __call__(self, *args, **kwargs):
        print('请求前的操作')
        ret = self.old(*args, **kwargs)  
        print('请求之后操作')
        return ret


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

3)自带的全局中间件before_request

@app.before_request
def xxx():
    if request.path == '/login':
        return None       # return None 接着执行视图 有返回值就地返回
        # 或者 return
    if request.form.get('user'):
        return None
    return redirect('/login')

4) after_request

@app.before_request
def x1():
   print('before')

@app.after_request
def x2(response):    # 必须有response
    print('after')
    return response 

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

执行打印结果
before
index
after

5)before_first_request

只有第一次请求才执行一次

@app.before_first_request
def

6)errorhander()

自定义404错误页面

@app.errorhander(404)
def not_found(arg):
    print(arg)     # 错误信息
    return 'xx' 

 

7) template_global()

@app.template_global()
def sb(a1, a2):
    return a1 + a2

全局调用
{{ sb(1,  9) }}

8) template_filter()

@app.template_filter()
def db(a1, a2, a3):
   return a1 + a2 + a3 


全局调用
{{ 1|db(2, 3) }}

 

六 flask 的CBV

from flask import Flask, views

app = Flask(__name__)


class UserView(views.MethodView):
    def get(self, *args, **kwargs):
        return "GET"


app.add_url_rule('/user', None, UserView.as_view('随便起的别名'))

 

七 url 自定义正则

from werkzeug.routing import BaseConverter
from flask import Flask, url_for

app = Flask(__name__)


class RegexConverter(BaseConverter):
    # 自定义正则
    def __init__(self, map, regex):
        super(RegexConverter, self).__init__(map)
        self.regex = regex

    def to_python(self, value):
        # 路由匹配时, 匹配成功后传递给视图函数中参数的值
        # 拿到路由匹配到的参数, 并做处理
        return int(value)

    def to_url(self, value):
        val = super().to_url(value)
        return val


app.url_map.converters['reg'] = RegexConverter


@app.route('/index/')
def index(nid):
    print("ffffffff", url_for('index', nid=999))
    return redirect(url_for('index', nid=666))
  • to_python 只要使了转换器,一直会被调用
  • to_url 只有在重定向了,并且路由上有参数的时候才会被调用

当我们重定向了,并传递参数的时候,参数会先到to_url,返回的值会去匹配路由上的正则。
如果匹配上了,就把匹配到参数传到 to_python ,这个方法返回的值才会到视图函数中。
如果匹配不上,就会报404错误。
 

八 蓝图

详见 https://blog.csdn.net/DeskyAki/article/details/89341262   

九 上下文管理

详见 https://blog.csdn.net/DeskyAki/article/details/89648260

十 flask 上传文件

前端

后台

import os 
def upload():
    if request.method == "GET":
        return render_template('xx')
    file_obj = request.fiels.get('code')
    print(file_obj.filename)     # 打印文件名字
    print(file_obj.stream)       # 打印文件内容
    file_obj.save(file_obj.filename)     # 自动保存,文件名是filename的值

或者
    # 指定保存到的路径
    file_path = os.path.join("files", file_obj.filename)
    file_obj.save(file_obj.filename) 
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 7
限制文件大小                         1K * 1024 * 7 = 7M

十一 jinja模板

详见 https://blog.csdn.net/DeskyAki/article/details/97120847    这篇博客总结的很全面

十二  flask多APP应用

from flask import Flask,
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple

app1 = Flask("app1")
# app1.config['DB'] = 123

app2 = Flask("app2")
# app2.config['DB'] = 234


@app1.route('/a')
def app1index():
    return 'app1'


@app2.route('/b')
def app2index():
    return 'app2'


app = DispatcherMiddleware(app1, {
    '/app2': app2,
})


if __name__ == '__main__':
    run_simple('localhost', 5000, app)


# 访问http://localhost:5000/a
# 访问http://localhost:5000/app2/b
from 前面的文件 import app1, app2

with app1.app_content():             # 进入app01
    pass                             # 创建数据库
    with app.app_content():          # 进入app02
        pass                         # 创建数据库
        

 

 

 

 

你可能感兴趣的:(flask)