摘要:視圖高級和這個方法是用來添加與視圖函數(shù)的映射。小例子如下請求上下文的定義,結(jié)合類視圖之前我們接觸的視圖都是函數(shù),所以一般簡稱視圖函數(shù)。
視圖高級 app.route和app.add_url_rule
app.add_url_rule
app.add_url_rule("/list/",endpoint="myweb",view_func=my_list)
這個方法是用來添加url與視圖函數(shù)的映射。如果沒有填寫endpoint那么會默認使用view_func的名字來作為endpoint。
因此在使用url_for的時候,就要看在映射的時候有沒有傳遞endpoint參數(shù),如果傳遞了,那么就使用endpoint指定的字符串。
付過沒有使用的話就使用view_func定義的名字。
app.route(rule,**options)裝飾器
這個裝飾器的底層就是用add_url_rule來實現(xiàn)url與視圖函數(shù)映射的。
小例子如下:
from flask import Flask,url_for app = Flask(__name__) app.config.update({ "DEBUG":True, "TEMPLATES_AUTO_RELOAD":True }) @app.route("/",endpoint="index") def hello_world(): print(url_for("myweb")) return "Hello World!" def my_list(): return "list page!" app.add_url_rule("/list/",endpoint="myweb",view_func=my_list) #請求上下文的定義,結(jié)合url_for with app.test_request_context(): print(url_for("index")) if __name__ == "__main__": app.run()類視圖
之前我們接觸的視圖都是函數(shù),所以一般簡稱視圖函數(shù)。
其實視圖也可以基于類來實現(xiàn),類視圖的好處是支持繼承,但是類視圖不能跟函數(shù)視圖一樣,
寫完類視圖還需要通過app.add_url_rule(url_rule,view_func)來進行注冊。以下將對兩種類視圖進行講解
標準類視圖必須繼承自flask.views.View
必須實現(xiàn)dispatch_request方法,以后請求過來以后,會執(zhí)行這個方法。這個方法的返回值就相當(dāng)于是之前的函數(shù)視圖一樣,也必須返回Request或者子類的對象(字符串或者元組)。
必須是通過app.add_url_rule(rule,endpoint,view_func)來做url映射。
view_func這個參數(shù),要使用as_view這個方法來轉(zhuǎn)換
如果指定了endpoint,那么在使用url_for反轉(zhuǎn)的時候,就要使用endpoint指定的那個值,如果沒有指定那個值,就使用as_view中指定的視圖名字來作為反轉(zhuǎn)。
類視圖有以下的好處,可以將一些共性的東西抽取出來放到父視圖中,子視圖直接繼承就可以了,但是也不是說所有的視圖都要使用類視圖,這個要根據(jù)實際情況來定。
小例子:
from flask import Flask,views,url_for app = Flask(__name__) class ListView(views.View): def dispatch_request(self): return "list view" #app.add_url_rule("/list/",endpoint="list",view_func=ListView.as_view("list")) app.add_url_rule("/list/",view_func=ListView.as_view("list")) with app.test_request_context(): print(url_for("list")) @app.route("/") def hello_world(): return "Hello World!" if __name__ == "__main__": app.run(debug=True)
類視圖的小例子:
from flask import Flask,url_for,views,jsonify,render_template app = Flask(__name__) app.config.update({ "DEBUG":True, "TEMPLATES_AUTO_RELOAD":True }) #自定義封裝,返回json數(shù)據(jù) class JSONView(views.View): def get_data(self): raise NotImplementedError def dispatch_request(self): return jsonify(self.get_data()) class ListView(JSONView): def get_data(self): return { "username":"wanghui", "password":123456, } app.add_url_rule("/list/",endpoint="my_list",view_func=ListView.as_view("list")) #有幾個視圖,需要返回相同的變量(廣告頁面) class ADSView(views.View): def __init__(self): super(ADSView, self).__init__() self.context = { "ads":"今年過節(jié)不收禮,收禮只收腦白金" } class RegistView(ADSView): def dispatch_request(self): self.context.update({"username":"abcd"}) return render_template("register.html",**self.context) class LoginView(ADSView): def dispatch_request(self): return render_template("login.html",**self.context) # class LoginView(views.View): # def dispatch_request(self): # return render_template("login.html",ads="今年過節(jié)不收禮,收禮只收腦白金") # class RegistView(views.View): # def dispatch_request(self): # return render_template("register.html",ads="今年過節(jié)不收禮,收禮只收腦白金") app.add_url_rule("/login/",view_func=LoginView.as_view("login")) app.add_url_rule("/regist/",view_func=RegistView.as_view("regist")) @app.route("/") def hello(): return "heello" if __name__ == "__main__": app.run()基于調(diào)度方法的視圖
根據(jù)請求方法來執(zhí)行不同的方法的,如果用戶發(fā)送的是get請求,就會執(zhí)行這個類的get方法;如果用戶發(fā)起的是post方法,就會執(zhí)行這個類的post方法。其他的方法類似,這種方法使得代碼更加簡潔,使得執(zhí)行g(shù)et請求的代碼放在get方法中,post請求的代碼放在posy方法中。就不需要跟之前的request.method == "POST"來搞了。
小例子
py
from flask import Flask,views,render_template,request app = Flask(__name__) class LoginView(views.MethodView): def __render(self,error=None): return render_template("login.html",error=error) def get(self,error=None): # return render_template("login.html",error=error) return self.__render() def post(self): username = request.form.get("username") password = request.form.get("password") if username == "wanghui" and password == "111111": return "login success" else: # return render_template("login.html",error="username or password error,retry!") # return self.get(error="username or password error,retry!") return self.__render(error="username or password error,retry!") app.add_url_rule("/login/",view_func=LoginView.as_view("login")) @app.route("/") def hello_world(): return "Hello World!" if __name__ == "__main__": app.run(debug=True,port=9090)
login.html
類視圖上面使用裝飾器login
兩種類型的裝飾器
如果使用的是函數(shù)視圖, 那么定義的裝飾器必須放在app.route下面,否則起不到任何作用
類視圖的裝飾器,需要重寫類視圖的decorators類屬性,里面裝的就是所有的裝飾器
小例子:
from flask import Flask,request,views from functools import wraps app = Flask(__name__) #定義裝飾器 def login_required(func): @wraps(func) def wrapper(*args,**kwargs): username = request.args.get("username") if username and username == "wanghui": return func(*args,**kwargs) else: return "請先登錄" return wrapper @app.route("/settings/") @login_required def settings(): return "這是設(shè)置頁面" #這樣請求就行http://127.0.0.1:9091/settings/?username=wanghui #類視圖添加裝飾器 class ProfileView(views.View): decorators = [login_required] def dispatch_request(self): return "這是個人中心" app.add_url_rule("/profile/",view_func=ProfileView.as_view("profile"))藍圖
將大型項目分層解耦,實現(xiàn)模塊化,結(jié)構(gòu)更加清晰??梢詫⑾嗤哪K放在同一個藍圖下,同一個文件夾中。方便管理。
基本語法:
在藍圖文件中導(dǎo)入Blueprint
from flask import Blueprint user_bp = Blueprint("user",__name__) #相當(dāng)于是定義`app = Flask(__name__)`
在主app文件中注冊藍圖
from blueprints.user import user_bp app.regist_blueprint(user_bp) #實現(xiàn)注冊藍圖
如果想要某個藍圖下的所有URL的時候有個前綴,那么可以在定義藍圖的時候加上url_prefix
from flask import Blueprint user_bp = Blueprint("user",__name__,url_prefix="/user") # 特別注意斜杠藍圖中的模板文件
藍圖模板文件查找:
如果項目中的templates文件夾中存在對應(yīng)的模板文件,就可以直接使用
如果項目中的templates文件夾中存在相應(yīng)的模板文件,那么就在定義藍圖的指定路徑中查找,可以設(shè)置相對路徑,就要在藍圖文件相同路徑下的文件夾。
from flask import Blueprint,render_template news_bp = Blueprint("news",__name__,url_prefix="/news",template_folder="news") @news_bp.route("/list/") def news_list(): return render_template("news_list.html")
藍圖中的靜態(tài)文件查找:
在模板文件中,加載靜態(tài)文件,如果使用url_for("static"),那么只會在app指定的靜態(tài)文件夾目錄下查找靜態(tài)文件
如果在加載靜態(tài)文件的時候置頂了藍圖的名字,比如url_for("news.static"),那么會到藍圖指定的static_folder下查找靜態(tài)文件。
url_for反轉(zhuǎn)藍圖注意事項注意url_for到藍圖中的視圖函數(shù)的時候,要反轉(zhuǎn)藍圖中的視圖函數(shù)為url,那么就用該在使用url_for的時候使用url_for("news.news_list")不然就找不到這個endpoint。
即使在同一個藍圖中,反轉(zhuǎn)視圖函數(shù),也要制定藍圖的名字
子域名實現(xiàn)使用藍圖技術(shù)
在創(chuàng)建藍圖對象的時候要使用subdomain來指定這個子域名
from flask import Blueprint cms_bp = Blueprint("cms",__name__,subdomain="cms")
需要在app文件中配置app.config["SERVER_NAME"]="baidu.com"來指定跟域名
app.config["SERVER_NAME"] = "crop.com:9099"
修改hosts文件配置解析
127.0.0.1 crop.com 127.0.0.1 cms.crop.com
5.訪問
cms.crop.com:9099綜合實例代碼
目錄結(jié)構(gòu)
blue_print_e ├── blue_print_e.py ├── blueprints │ ├── bok.py │ ├── cms.py │ ├── movie.py │ ├── news_css │ │ └── news_list.css │ ├── news.py │ ├── news_tmp │ │ └── news_list.html │ └── user.py ├── static │ └── news_list.css └── templates ├── index.html └── news_list.html
主app文件blue_print_e.py
from flask import Flask,url_for,render_template from blueprints.user import user_bp from blueprints.news import news_bp from blueprints.cms import cms_bp app = Flask(__name__) app.config["SERVER_NAME"] = "crop.com:9099" app.register_blueprint(user_bp) app.register_blueprint(news_bp) app.register_blueprint(cms_bp) # ip地址不能有子域名 @app.route("/") def hello_world(): print(url_for("news_tmp.news_list")) #使用藍圖名字.視圖函數(shù)的名字 return render_template("index.html") if __name__ == "__main__": app.run(debug=True,port=9099)
blueprints/news.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Blueprint,render_template,url_for news_bp = Blueprint("news_tmp",__name__,url_prefix="/news_tmp",template_folder="news_tmp",static_folder="news_css") @news_bp.route("/list/") def news_list(): print(url_for("news.news_detail")) return render_template("news_list.html") @news_bp.route("/detail") def news_detail(): return "詳情頁面"
blueprints/user.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Blueprint user_bp = Blueprint("user",__name__,url_prefix="/user") @user_bp.route("/profile/") def profile(): return "個人中心" @user_bp.route("/settings/") def settings(): return "設(shè)置頁面"
blueprint/cms.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Blueprint cms_bp = Blueprint("cms",__name__,subdomain="cms") @cms_bp.route("/") def index(): return "cms index"
blueprints/news_css/
body { color: fuchsia; font-size: 90px; background: red; }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/52281.html
摘要:視圖高級和這個方法是用來添加與視圖函數(shù)的映射。小例子如下請求上下文的定義,結(jié)合類視圖之前我們接觸的視圖都是函數(shù),所以一般簡稱視圖函數(shù)。 視圖高級 app.route和app.add_url_rule app.add_url_rule app.add_url_rule(/list/,endpoint=myweb,view_func=my_list) 這個方法是用來添加url與視圖函數(shù)...
摘要:視圖高級和這個方法是用來添加與視圖函數(shù)的映射。小例子如下請求上下文的定義,結(jié)合類視圖之前我們接觸的視圖都是函數(shù),所以一般簡稱視圖函數(shù)。 視圖高級 app.route和app.add_url_rule app.add_url_rule app.add_url_rule(/list/,endpoint=myweb,view_func=my_list) 這個方法是用來添加url與視圖函數(shù)...
摘要:類視圖簡介視圖是一個可調(diào)用的對象,它接收一個請求然后返回一個響應(yīng),這個可調(diào)用對象可以不只是函數(shù),提供一些可以用作視圖的類基于類的視圖使用對象實現(xiàn)視圖,它提供除函數(shù)視圖之外的另外一種方式屬性添加未知的請求方法方法將類視圖轉(zhuǎn)換成可被調(diào)用的函數(shù)視 類視圖 簡介 視圖是一個可調(diào)用的對象,它接收一個請求然后返回一個響應(yīng),這個可調(diào)用對象可以不只是函數(shù),Django提供一些可以用作視圖的類基于類的視...
閱讀 4012·2021-11-18 13:22
閱讀 1829·2021-11-17 09:33
閱讀 2886·2021-09-26 09:46
閱讀 1220·2021-08-21 14:11
閱讀 2896·2019-08-30 15:53
閱讀 2717·2019-08-30 15:52
閱讀 1914·2019-08-30 10:52
閱讀 1528·2019-08-29 15:30