2012-12-21 51 views
3

我對不同的web框架(Django,web.py,Pyramid和CherryPy)有一些經驗,我想知道哪一個更容易,希望更清晰實現路線調度基於所述「接受」報頭和HTTP方法例如一個不同的「觀看/處理程序」:基於Python web框架中Accept頭的路由請求

Accept: text/html 
POST /post/ 

所以該請求被路由到:

Accept: application/json 
POST /post/ 

比處理不同MIME「application/json」和H的相應處理程序的特定視圖TTP方法「POST」。

我知道如何在CherryPy中實現類似的功能,但是我沒有將CherryPy工具用於請求的內部重定向,因爲我直接調用具體的方法而不是從調度程序自動調用。另一種選擇是從零開始實施全新的調度程序,但這是最後一個選項。

我知道在/post.json/post/.json之類的URL中使用擴展名的替代方法,但是我期望保持相同的url?

+0

這個問題很難一次回答所有的框架,對我來說這太籠統了。對於金字塔,使用[查看謂詞](http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/viewconfig.html#predicate-arguments),註冊兩個視圖,每個視圖使用不同的accept謂詞。 –

+0

@MartijnPieters是的,我認爲你是對的,它太寬泛:(但你的選擇似乎是一個很好的方法來做到這一點,我並沒有期待所有框架的答案只是在其中之一的方式來做到這一點 – cyraxjoe

+0

好的,如果這對你來說已經足夠了,那就解決吧。:-) –

回答

12

如果你正在尋找的是一個框架,可以很容易地做到這一點,然後使用pyramid

金字塔視圖的定義是用predicates進行的,而不僅僅是路徑,只有所有謂詞匹配時視圖纔會匹配。一個這樣的謂詞是謂詞,它完全符合你想要的;使視圖切換取決於Accept頭容易和簡單:

from pyramid.view import view_config 

@view_config(route_name='some_api_name', request_method='POST', accept='application/json') 
def handle_someapi_json(request): 
    # return JSON 

@view_config(route_name='some_api_name', request_method='POST', accept='text/html') 
def handle_someapi_html(request): 
    # return HTML 
0

我不確定你的意思是「內部重定向」,但是如果你看看the code,你可以看到tools.accept是一個非常薄的包裝,圍繞着lib.cptools.accept,你可以從你自己的代碼中輕鬆調用。把它遞給你的服務器可以發送的內容類型列表,並且它會告訴你客戶端喜歡哪一個,或者如果你發出的類型和客戶端接受的類型不重疊,就會引發406。

+0

特別是在cherrypy中,我想的是[this](https://gist.github.com/4356820) ), 你怎麼看? – cyraxjoe

+0

我剛剛在早上/晚上寫了[這個](https://gist.github.com/4358637),這是我想要的櫻桃,是的,它有點複雜,可能我會改進之後得到一些睡眠或聖誕節後:)。 – cyraxjoe

4

我需要做到這一點在Django,所以我寫了一箇中間件,使其成爲可能:http://baltaks.com/2013/01/route-requests-based-on-the-http-accept-header-in-django

下面是代碼:

# A simple middleware component that lets you use a single Django 
# instance to serve multiple versions of your app, chosen by the client 
# using the HTTP Accept header. 
# In your settings.py, map a value you're looking for in the Accept header 
# to a urls.py file. 
# HTTP_HEADER_ROUTING_MIDDLEWARE_URLCONF_MAP = { 
#  u'application/vnd.api-name.v1': 'app.urls_v1' 
# } 

from django.conf import settings 

class HTTPHeaderRoutingMiddleware: 

    def process_request(self, request): 
     try: 
      for content_type in settings.HTTP_HEADER_ROUTING_MIDDLEWARE_URLCONF_MAP: 
       if (request.META['HTTP_ACCEPT'].find(content_type) != -1): 
        request.urlconf = settings.HTTP_HEADER_ROUTING_MIDDLEWARE_URLCONF_MAP[content_type] 
     except KeyError: 
      pass # use default urlconf (settings.ROOT_URLCONF) 

    def process_response(self, request, response): 
     return response 
+2

我認爲只要在這裏發佈代碼會更好,因爲它太短了。 – Tshepang

+0

好吧,我已經添加了代碼。 –

相關問題