摘要:視圖高級和這個方法是用來添加與視圖函數的映射。小例子如下請求上下文的定義,結合類視圖之前我們接觸的視圖都是函數,所以一般簡稱視圖函數。
視圖高級 app.route和app.add_url_rule
app.add_url_rule
app.add_url_rule("/list/",endpoint="myweb",view_func=my_list)
這個方法是用來添加url與視圖函數的映射。如果沒有填寫endpoint那么會默認使用view_func的名字來作為endpoint。
因此在使用url_for的時候,就要看在映射的時候有沒有傳遞endpoint參數,如果傳遞了,那么就使用endpoint指定的字符串。
付過沒有使用的話就使用view_func定義的名字。
app.route(rule,**options)裝飾器
這個裝飾器的底層就是用add_url_rule來實現url與視圖函數映射的。
小例子如下:
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) #請求上下文的定義,結合url_for with app.test_request_context(): print(url_for("index")) if __name__ == "__main__": app.run()類視圖
之前我們接觸的視圖都是函數,所以一般簡稱視圖函數。
其實視圖也可以基于類來實現,類視圖的好處是支持繼承,但是類視圖不能跟函數視圖一樣,
寫完類視圖還需要通過app.add_url_rule(url_rule,view_func)來進行注冊。以下將對兩種類視圖進行講解
標準類視圖必須繼承自flask.views.View
必須實現dispatch_request方法,以后請求過來以后,會執行這個方法。這個方法的返回值就相當于是之前的函數視圖一樣,也必須返回Request或者子類的對象(字符串或者元組)。
必須是通過app.add_url_rule(rule,endpoint,view_func)來做url映射。
view_func這個參數,要使用as_view這個方法來轉換
如果指定了endpoint,那么在使用url_for反轉的時候,就要使用endpoint指定的那個值,如果沒有指定那個值,就使用as_view中指定的視圖名字來作為反轉。
類視圖有以下的好處,可以將一些共性的東西抽取出來放到父視圖中,子視圖直接繼承就可以了,但是也不是說所有的視圖都要使用類視圖,這個要根據實際情況來定。
小例子:
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數據 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":"今年過節不收禮,收禮只收腦白金" } 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="今年過節不收禮,收禮只收腦白金") # class RegistView(views.View): # def dispatch_request(self): # return render_template("register.html",ads="今年過節不收禮,收禮只收腦白金") 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()基于調度方法的視圖
根據請求方法來執行不同的方法的,如果用戶發送的是get請求,就會執行這個類的get方法;如果用戶發起的是post方法,就會執行這個類的post方法。其他的方法類似,這種方法使得代碼更加簡潔,使得執行get請求的代碼放在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
兩種類型的裝飾器
如果使用的是函數視圖, 那么定義的裝飾器必須放在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 "這是設置頁面" #這樣請求就行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"))藍圖
將大型項目分層解耦,實現模塊化,結構更加清晰。可以將相同的模塊放在同一個藍圖下,同一個文件夾中。方便管理。
基本語法:
在藍圖文件中導入Blueprint
from flask import Blueprint user_bp = Blueprint("user",__name__) #相當于是定義`app = Flask(__name__)`
在主app文件中注冊藍圖
from blueprints.user import user_bp app.regist_blueprint(user_bp) #實現注冊藍圖
如果想要某個藍圖下的所有URL的時候有個前綴,那么可以在定義藍圖的時候加上url_prefix
from flask import Blueprint user_bp = Blueprint("user",__name__,url_prefix="/user") # 特別注意斜杠藍圖中的模板文件
藍圖模板文件查找:
如果項目中的templates文件夾中存在對應的模板文件,就可以直接使用
如果項目中的templates文件夾中存在相應的模板文件,那么就在定義藍圖的指定路徑中查找,可以設置相對路徑,就要在藍圖文件相同路徑下的文件夾。
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")
藍圖中的靜態文件查找:
在模板文件中,加載靜態文件,如果使用url_for("static"),那么只會在app指定的靜態文件夾目錄下查找靜態文件
如果在加載靜態文件的時候置頂了藍圖的名字,比如url_for("news.static"),那么會到藍圖指定的static_folder下查找靜態文件。
url_for反轉藍圖注意事項注意url_for到藍圖中的視圖函數的時候,要反轉藍圖中的視圖函數為url,那么就用該在使用url_for的時候使用url_for("news.news_list")不然就找不到這個endpoint。
即使在同一個藍圖中,反轉視圖函數,也要制定藍圖的名字
子域名實現使用藍圖技術
在創建藍圖對象的時候要使用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綜合實例代碼
目錄結構
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")) #使用藍圖名字.視圖函數的名字 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 "設置頁面"
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; }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/113231.html
摘要:視圖高級和這個方法是用來添加與視圖函數的映射。小例子如下請求上下文的定義,結合類視圖之前我們接觸的視圖都是函數,所以一般簡稱視圖函數。 視圖高級 app.route和app.add_url_rule app.add_url_rule app.add_url_rule(/list/,endpoint=myweb,view_func=my_list) 這個方法是用來添加url與視圖函數...
摘要:視圖高級和這個方法是用來添加與視圖函數的映射。小例子如下請求上下文的定義,結合類視圖之前我們接觸的視圖都是函數,所以一般簡稱視圖函數。 視圖高級 app.route和app.add_url_rule app.add_url_rule app.add_url_rule(/list/,endpoint=myweb,view_func=my_list) 這個方法是用來添加url與視圖函數...
摘要:類視圖簡介視圖是一個可調用的對象,它接收一個請求然后返回一個響應,這個可調用對象可以不只是函數,提供一些可以用作視圖的類基于類的視圖使用對象實現視圖,它提供除函數視圖之外的另外一種方式屬性添加未知的請求方法方法將類視圖轉換成可被調用的函數視 類視圖 簡介 視圖是一個可調用的對象,它接收一個請求然后返回一個響應,這個可調用對象可以不只是函數,Django提供一些可以用作視圖的類基于類的視...
閱讀 3061·2021-10-12 10:12
閱讀 1568·2021-09-09 11:39
閱讀 1844·2019-08-30 15:44
閱讀 2339·2019-08-29 15:23
閱讀 2898·2019-08-29 15:18
閱讀 2959·2019-08-29 13:02
閱讀 2687·2019-08-26 18:36
閱讀 733·2019-08-26 12:08