flask 即插視圖(Pluggable Views)和endpoint


endpoint經常使用flask的人肯定不會面生。其實我一直沒有關注過他是怎么尋址的,直到最近經常食用url_for這個函數才引起了我的注意。

url_for看源碼感覺實現挺復雜的,我們姑且不在這里糾結看到這一句:

def url_for(endpoint, **values):
    """Generates a URL to the given endpoint with the method provided.

傳入的第一個參數是endpoint,url_for函數會將掛在endpoint上面的viewfunction的url返回回來。

當我們在正常請求flask提供的函數的時候我們使用的尋址順序是 url -> endpoint -> viewfunction

當我們在有viewfunction想知道url的時候 尋址順序是 viewfunction -> endpoint -> url

 

而且當有一個藍圖被申明的時候,我們使用url_for要帶上藍圖的名稱例如:

ec_bp = Blueprint(
    'ec',
    __name__,
    template_folder='templates',
    static_folder='static')

一個藍圖是這樣

那么要找到這個藍圖下面的視圖函數使用url_for的時候要這樣。

url_for('ec.endpoint')

方能夠正常尋址。關於endpoint其他沒有什么好說的了。

 

下面來看看flask的即插視圖:

 即插視圖主要牽扯到兩個方面的東西,首先我們要理解一個重要的概念。我們在flask中使用的裝飾器路由地址與endpoint的綁定也可使用 

add_url_rule函數進行路由綁定

    def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
        """A helper method to register a rule (and optionally a view function)
        to the application.  The endpoint is automatically prefixed with the
        blueprint's name.

這里喔拷貝了一個 bluepoint上面的add_url_rule方法過來,其實都差不多,這里直接使用bluepoint上面的該方法可以自動進行endpoint尋址不用使用前綴所以還比較方便。綁定路由就是rule寫路由, endpoint寫綁定的endpoint  然后view_func寫使用哪個視圖函數的名字。

這里即插視圖在view_func上面一般使用類來做view_func,進行更靈活的管理。這樣使用

class RenderTemplateView(View):
    def __init__(self, template_name):
        self.template_name = template_name
    def dispatch_request(self):
        return render_template(self.template_name)
app.add_url_rule('/about', view_func=RenderTemplateView.as_view(
    'about_page', template_name='about.html'))

上面是官方文檔上的一個例子將類RenderTemplateView使用as_view 作為視圖函數 然后設置一個name 之后與/about的 url規則綁定在一起。

即插視圖繼承view 實現一個自己的dispatch_request的方法。 在執行這個視圖的時候會執行dispath_request這個函數里的內容,這樣就可以靈活運用這個特性。

另外 即插視圖 還可以繼承一個flask.view中的MethodView方法這樣可以自動路由到對應的方法下面去執行函數。

from flask.views import MethodView

class UserAPI(MethodView):
    def dispatch_request(self):
        return super(UserAPI, self).dispatch_reqeust() 
    
    def get(self):
        users = User.query.all()
        ...

    def post(self):
        user = User.from_form_data(request.form)
        ...

app.add_url_rule('/users/', view_func=UserAPI.as_view('users')

本來沒有重寫dispatch_request方法會調用繼承自MethodView的 dispatch_request方法路由給指定的http方法對應的函數。

這里我們再特殊處理一下,重寫父類的dispatch_reqeust方法先跑一波我們需要的邏輯,然后再調用父類的dispatch_request()方法來路由到指定的http方法上繼續執行函數。而且,這里繼續傳遞參數到父類的dispatch_reqeust方法上是沒有問題的。想傳還是可以傳。

可以看到這樣就避免了我們寫惡心的 request.method == 'post'這樣惡心的判斷,其實也不錯。

以上

 

Reference:

http://docs.jinkan.org/docs/flask/views.html  即插視圖flask api中文文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM