1. 程式人生 > >11.3 Flask 視圖,模板

11.3 Flask 視圖,模板

pos 模板 login scale style idt oot ror --

視圖

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()
befor/after_request 示例 技術分享圖片
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()
before_first_request 示例 技術分享圖片
@app.errorhandler(404)
def not_found(arg):
    print(arg)
    return "沒找到"
errorhandler 示例

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 視圖,模板