11.3 Flask 视图,模板
Posted shijieli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11.3 Flask 视图,模板相关的知识,希望对你有一定的参考价值。
视图
FBV
def index(nid):
""" 请求相关信息 * request.method * request.args * request.form * request.values * request.cookies * request.headers request.path request.full_path request.script_root request.url request.base_url request.url_root request.host_url request.host request.files obj = request.files[‘the_file_name‘] obj.save(‘/var/www/uploads/‘ + secure_filename(f.filename)) """
dic = {"k1":"v1"}
""" 返回响应体的4种形式 字符串 jsonify 模板 url """
# return "index"
# return jsonify(dic) # return render_template("xxx.html",dic=dic) # 可带数据传递 # return redirect(url_for("index")) # 跳转通过 url_for 反向解析
""" 定制响应头的时候构造响应体用到 make_response """
# 如果想设置响应头和回显cookie,就需要用到make_response
# response = make_response(render_template(‘index.html‘))
# response = make_response("字符串")
# response是flask.wrappers.Response类型
# response.delete_cookie(‘key‘)
# response.set_cookie(‘key‘, ‘value‘)
# response.headers[‘X-Something‘] = ‘A value‘
# return response
from flask import make_response,headers,set_cookie obj = make_response(jsonify(dic)) obj.headers["xxxxx"] = "123" obj.set_cookie("key","value") return obj
装饰器实现中间件功能
预备处理视图函数初始状态
@app.route(‘/index‘) def index(): if not session.get(‘user‘): return redirect(url_for(‘login‘)) return render_template(‘index.html‘,stu_dic=STUDENT_DICT)
视图级别加装,比较适用于对少量视图进行处理
import functools def auth(func): @functools.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(‘/index‘) @auth def index(): return render_template(‘index.html‘,stu_dic=STUDENT_DICT)
全局级别加装
@app.before_request def xxxxxx(): if request.path == ‘/login‘: return None if session.get(‘user‘): return None return redirect(‘/login‘)
除了 before_request 以外还有其他特殊装饰器:
1. before_request 谁先定义谁先执行 执行多个 before 的时候如果再中间有返回值,对于after 的执行直接执行最后一次定义的那个 2. after_request 谁后定义谁执行 3. before_first_request 4. template_global 5. template_filter 6. errorhandler
from flask import Flask app = Flask(__name__) @app.before_request def x1(): print(‘before:x1‘) return ‘滚‘ @app.before_request def xx1(): print(‘before:xx1‘) @app.after_request def x2(response): print(‘after:x2‘) return response @app.after_request def xx2(response): print(‘after:xx2‘) return response @app.route(‘/index‘) def index(): print(‘index‘) return "Index" @app.route(‘/order‘) def order(): print(‘order‘) return "order" if __name__ == ‘__main__‘: app.run()
from flask import Flask app = Flask(__name__) @app.before_first_request def x1(): print(‘123123‘) @app.route(‘/index‘) def index(): print(‘index‘) return "Index" @app.route(‘/order‘) def order(): print(‘order‘) return "order" if __name__ == ‘__main__‘: app.run()
@app.errorhandler(404) def not_found(arg): print(arg) return "没找到"
CBV
def auth(func): def inner(*args, **kwargs): result = func(*args, **kwargs) return result return inner # 继承自views.MethodView 采用CBV写法时,为了简单,都是采用继承MethodView的方式写的 class IndexView(views.MethodView): # methods = [‘POST‘] #只允许POST请求访问 decorators = [auth,] #如果想给所有的get,post请求加装饰器,就可以这样来写,也可以单个指定 def get(self): #如果是get请求需要执行的代码 v = url_for(‘index‘) print(v) return "GET" def post(self): #如果是post请求执行的代码 return "POST" app.add_url_rule(‘/index‘, view_func=IndexView.as_view(name=‘index‘)) #name指定的是别名,会当做endpoint使用
def auth(func): def inner(*args, **kwargs): print(‘before‘) result = func(*args, **kwargs) print(‘after‘) return result return inner # 也可以再往上继承自View class IndexView(views.View): methods = [‘GET‘] decorators = [auth, ] # 如果继承自View,就需要dispatch_request def dispatch_request(self): print(‘Index‘) return ‘Index!‘ app.add_url_rule(‘/index‘, view_func=IndexView.as_view(name=‘index‘)) # name=endpoint
模板
基本数据类型
可以执行python语法,如:dict.get(), list[‘xx‘]
比django 更加亲近于 python
传入函数
- - django,自动执行
- - flask,不自动执行,需要自己加 " () " 了
简单的示例
def func1(arg):
return "hello" + arg
@app.route("/index")
def index():
return render_template("s5index.html",f=func1) # 传入函数
<body> <!-- 传入函数 --> <!-- |safe 防xss攻击 --> <h1>{{f(‘羊驼‘)|safe}}</h1> </body>
定义函数
@app.template_global() def sb(a1, a2): # {{sb(1,9)}} return a1 + a2 @app.template_filter() def db(a1, a2, a3): # {{ 1|db(2,3) }} return a1 + a2 + a3
模板继承
Flask使用的时Jinja2模板,所以其语法和Django无差别
layout.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>模板</h1> {% block content %}
{% endblock %} </body> </html>
tpl.html
{% extends "layout.html"%}
{% block content %}
{{users.0}}
{% endblock %}
include
用法同django
{% include "form.html" %} form.html <form> asdfasdf </form>
宏
定制一段 HTML 代码。通过宏可以多次调用,实现冗余代码的封装以及复用性
{% macro ccccc(name, type=‘text‘, value=‘‘) %} <h1>宏</h1> <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> <input type="submit" value="提交"> {% endmacro %} {{ ccccc(‘n1‘) }} {{ ccccc(‘n2‘) }}
安全
- 前端:
{{u|safe}}
- 后端:
Markup("<input type=‘text‘ value=%s />"%(arg,))
以上是关于11.3 Flask 视图,模板的主要内容,如果未能解决你的问题,请参考以下文章