Flask視圖函數與模板語法

1.Django中的CBV模式

Flask視圖函數與模板語法

2.Flask中的CBV和FBV

def auth(func):
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        return result
    return inner

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即FBV中的endpoint,指別名

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

類視圖及其使用

視圖函數不能面向對象編程,利用類視圖來代替視圖函數來解決這個問題html

導入視圖類 View前端

 from flask.views import Viewjava

編寫一個視圖子類python

class MyView(View): # MyView繼承於View

    def test(self):  #  自定義的方法
        return '測試類視圖'

    def dispatch_request(self):   # 必須重寫這個方法
        resp = self.test()
        return resp

利用View子類獲取到一個視圖方法django

    MyView.as_view('test')編程

      注意:.as_view方法的放回值是一個方法,並且該方法的名字就是傳進去的參數json

將獲取到的視圖方法和路徑對應起來flask

app.add_url_rule('/test/', view_func=MyView.as_view('test')) # MyView.as_view('test') 返回的是一個方法

類視圖的原理後端

    把as_view方法返回的結果賦值給view_func
    as_view方法返回的是一個方法(注意:as_view方法傳入的參數就是as_view返回的那個方法的名字),該方法會調用dispatch_request方法
    一旦路由進來,就會調用 dispatch_request 方法
    類視圖的目的就是實現邏輯分離、方便管理cookie

from flask import Flask
from flask.views import View

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello World'

class MyView(View): # MyView繼承於View

    def test(self):  #  自定義的方法
        return '測試類視圖'

    def dispatch_request(self):   # 必須重寫這個方法
        resp = self.test()
        return resp


app.add_url_rule('/test/', view_func=MyView.as_view('test')) # MyView.as_view('test') 返回的是一個方法

print(app.url_map)

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

# 把as_view方法返回的結果賦值給view_func
# as_view方法返回的是一個方法(注意:as_view方法傳入的參數就是as_view返回的那個方法的名字),該方法會調用dispatch_request方法
# 一旦路由進來,就會調用 dispatch_request 方法
# 類視圖的目的就是實現邏輯分離、方便管理

方法視圖及其使用

利用視圖函數實現不一樣的請求執行不一樣的邏輯時比較複雜,須要在視圖函數函數中進行判斷;若是利用方法視圖實現就比較簡單

@app.route('/test/', methods=['GET', 'POST'])
def test():
    if request.method == 'GET':
        # 作GET的事情
        pass
    elif request.method == 'POST':
        # 作POST的事情
        pass
    return '測試'

導入方法視圖類  
    from flask.views import MethodView

建立方法視圖子類

class TestMethodView(MethodView):
    def get(self):
        # 處理Get請求
        return 'GET請求'
    def post(self):
        # 處理post請求
        return 'POST請求'

注意:視圖類中的方法就是支持的請求類型

Flask視圖函數與模板語法

利用方法視圖子類建立一個視圖函數
TestMethodView.as_view('testMethodView')
注意:as_view返回的是一個視圖函數,並且該視圖函數逇名稱就是傳進去的參數

將獲取到的視圖方法和路徑對應起來
app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))

from flask import Flask
from flask import request
from flask.views import MethodView

app = Flask(__name__)

@app.route('/')
def index():
    return '測試主頁面'

@app.route('/test/', methods=['GET', 'POST'])
def test():
    if request.method == 'GET':
        # 作GET的事情
        pass
    elif request.method == 'POST':
        # 作POST的事情
        pass
    return '測試'

class TestMethodView(MethodView):
    def get(self):
        # 處理Get請求
        return 'GET請求'
    def post(self):
        # 處理post請求
        return 'POST請求'

app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))
# method = TestMethodView.as_view('testMethodView');
# app.add_url_rule('/test02/<name>/', view_func=method, methods=['GET'])

print(app.url_map)

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

雖然在方法視圖中定義的函數就是支持的請求類型,可是咱們能夠在配置路徑時指定哪一個路徑對應哪中類型的請求

利用方法視圖子類獲取一個名字爲testMethodView02的視圖函數,該視圖函數只能支持GET請求,並且支持轉換器

method02 = TestMethodView.as_view('testMethodView02');
app.add_url_rule('/test02/<name>/', view_func=method02, methods=['GET'])

利用利用方法視圖子類獲取一個名字爲testMethodView03的視圖函數,該視圖函數只能支持POST請求

method03 = TestMethodView.as_view('testMethodView03')
app.add_url_rule('/test03/', view_func=method03, methods=['POST'])

 模擬POST請求

Flask視圖函數與模板語法

from flask import Flask
from flask import request
from flask.views import MethodView

app = Flask(__name__)

@app.route('/')
def index():
    return '測試主頁面'

@app.route('/test/', methods=['GET', 'POST'])
def test():
    if request.method == 'GET':
        # 作GET的事情
        pass
    elif request.method == 'POST':
        # 作POST的事情
        pass
    return '測試'

class TestMethodView(MethodView):
    def get(self, name):
        # 處理Get請求, 也能夠在這些方法中調用其餘的方法
        return 'GET請求' + name
    def post(self):
        # 處理post請求, 也能夠在這些方法中調用其餘的方法
        return 'POST請求'

# app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))
method02 = TestMethodView.as_view('testMethodView02');
app.add_url_rule('/test02/<name>/', view_func=method02, methods=['GET'])
method03 = TestMethodView.as_view('testMethodView03')
app.add_url_rule('/test03/', view_func=method03, methods=['POST'])

print(app.url_map)

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

6、請求與響應

from flask import Flask
 from flask import request
 from flask import render_template
 from flask import redirect
 from flask import make_response

    app = Flask(__name__)


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

        # 請求相關信息
        # 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))

        # 響應相關信息
        # return "字符串"
        # return render_template('html模板路徑',**{})
        # return redirect('/index.html')

        # response = make_response(render_template('index.html'))
        # response是flask.wrappers.Response類型
        # response.delete_cookie('key')
        # response.set_cookie('key', 'value')
        # response.headers['X-Something'] = 'A value'
        # return response


        return "內容"

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

from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response
from urllib.parse import urlencode,quote,unquote
app = Flask(__name__)

@app.route('/index',endpoint='xx')
def index():
    from werkzeug.datastructures import ImmutableMultiDict
  =================
    # get_data = request.args
    # get_dict = get_data.to_dict()
    # get_dict['xx'] = '18'
    # url = urlencode(get_dict)
    # print(url)
  ====================
    # print(request.query_string)
    # print(request.args)
  ==========================
    # val = "%E6%8A%8A%E5%87%A0%E4%B8%AA"
    # print(unquote(val))   #把上面這樣的數據轉換成中文
    #
    # return "Index"

    # return "Index"
    # return redirect()
    # return render_template()
    # return jsonify(name='alex',age='18')  #至關於JsonResponse
  =======================
    response = make_response('xxxxx')   ##若是是返回更多的值,cookie,headers,或者其餘的就可用它
    response.headers['xxx'] = '123123'
    return response


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

7、模板語法

一、模板的使用

Flask使用的是Jinja2模板,因此其語法和Django無太大差異

Flask中模板裏面,執行函數時,須要帶()才執行

1.爲了防止xss攻擊,加了驗證,因此頁面上顯示字符串的形式,解決辦法,有兩種方法

方法一:在後端使用Markup,等價於Django裏的mark_safe

 v = Markup("<input type='text' />")

方法二:在前端使用safe

{{ v1|safe }}

2.靜態文件的兩種導入方式 

目錄結構:

Flask視圖函數與模板語法

方式一:

Flask視圖函數與模板語法

方式二:

Flask視圖函數與模板語法

3.flask中模板語法不提示,解決辦法

Flask視圖函數與模板語法

點擊選擇jinja2

二、自定義模板方法

Flask中自定義模板方法的方式和Bottle類似,建立一個函數並經過參數的形式傳入render_template,

run.py

from flask import Flask,url_for,render_template,Markup
app = Flask(__name__)

def test(a,b):    #自定義的標籤,此方法在使用時,須要在render_temlate中傳入到指定以頁面使用
    return a+b

@app.template_global()   # 不須要傳入,可直接在頁面使用
def sb(a1, a2):
    return a1 + a2 + 100


@app.template_filter()    #不須要傳入,使用時要在一個值(此值做爲第一個參數傳入到過濾器中)的後面加入|,而後再加參數
def db(a1, a2, a3):
    return a1 + a2 + a3

@app.route('/index')
def index():
    v1 = "字符串"
    v2 = [11,22,33]
    v3 = {"k1":"v3","sdf":"sdgfgf"}
    v4 = "<input type='text' />"
    v5 = Markup("<input type='text' />")
    return render_template("index.html",v1=v1,v2=v2,v3=v3,v4=v4,v5=v5,test=test)

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

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width">
    <title>Title</title>
</head>
<body>
{{ v1 }}
<ul>
    {% for foo in v2 %}
       <li>{{ foo }}</li>
    {% endfor %}
    {{ v2.1 }}

    {% for k,v in v3.items() %}
    <li>{{ k }} {{ v }}</li>
    {% endfor %}
    {{ v3.k1 }}
    {{ v3.get("k1") }}

    {{ v4|safe }}
    {{ v5 }}

    <h1>{{ test(1,2) }}</h1>
    <p>{{ sb(1,2) }}</p>
    <p>{{ 1| db(2,3) }}</p>
</ul>
</body>
</html>

PS:模板繼承的方法和django的同樣。

3.宏

只有定義的東西在不少地方去使用的時候纔去用它,

html

{% macro xx(name, type='text', value='') %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
  <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
  <input type="{{ type }}" name="{{ name }}" value="{{ value }}">

{% endmacro %}

{{ xx('n1') }} 

至關於在頁面上定義了一個名爲xx的'函數',這個函數接收3個參數,咱們給type和value寫上了默認值,此時調用,咱們還須要傳入一個參數,咱們此時傳入了一個n1,則

頁面上會生成3個input框,name都爲n1

原文連接:

https://www.cnblogs.com/huchong/p/8227606.html

 


Flask視圖函數與模板語法

識別圖中二維碼,領取python全套視頻資料

相關文章
相關標籤/搜索