python Django와 CherryPy가 HTTP 동사 기반의 파견을 기본적으로 지원하지 않는 이유는 무엇입니까?



cherrypy django (4)

장고에 대한 결정은 보통 GETPOST 만으로 충분하기 때문에 이루어 졌다고 생각합니다. 프레임 워크를 요구 사항에 맞게 간단하게 유지합니다. 어떤 동사가 사용되었는지에 대해 "신경 쓰지 않는"것은 매우 편리합니다.

그러나 동사에 기반한 파견을 수행 할 수있는 많은 다른 프레임 워크가 있습니다. 나는 werkzeug 좋아 werkzeug , 자신의 파견 코드를 쉽게 정의 할 수 있으므로, 원하는대로 무엇이든 원하는대로 파견 할 수 있습니다.

GET, DELETE 또는 PUT하는 것보다 URL에 POST하는 것은 동일하지 않습니다. 이러한 행동은 근본적으로 다릅니다. 그러나 장고는 파견기구에서 장고를 무시하는 것 같습니다. 기본적으로 HTTP 동사를 완전히 무시하거나 모든보기에서이 작업을 수행해야합니다.

def my_view(request, arg1, arg2):
    if request.method == 'GET':
        return get_view(request, arg1, arg2)
    if request.method == 'POST':
        return post_view(request, arg1, arg2)
    return http.HttpResponseNotAllowed(['GET', 'POST'])

웹에서 발견 한 몇 가지 해결책 (동사 기반 파견 용이 스 니펫 또는 동사 요구 사항 용 데코레이터 )은 명확하게 해결 방법이므로 매우 우아하지 않습니다.

CherryPy의 상황은 똑같은 것 같습니다. 내가 아는 유일한 프레임 워크는 web.py와 Google App Engine입니다.

나는 이것을 웹 프레임 워크의 심각한 디자인 결함으로 본다. 누구가 동의합니까? 또는 무시한 이유 / 요구 사항을 토대로하는 신중한 결정입니까?


장고를 말할 수는 없지만 CherryPy에서는 하나의 config 항목으로 HTTP 동사 당 하나의 기능을 사용할 수 있습니다.

request.dispatch = cherrypy.dispatch.MethodDispatcher()

그러나, 나는 그것이 바람직하지 않은 몇 가지 상황을 보았다.

한 가지 예는 동사에 관계없이 강제 리디렉션입니다.

또 다른 경우는 대다수 핸들러가 GET만을 처리하는 경우입니다. 이 경우 특히 천 페이지 핸들러를 모두 '가져 오기'라는 이름으로 지정하는 것이 귀찮습니다. 데코레이터에서 함수 이름보다 표현하는 것이 더 낫습니다.

def allow(*methods):
    methods = list(methods)
    if not methods:
        methods = ['GET', 'HEAD']
    elif 'GET' in methods and 'HEAD' not in methods:
        methods.append('HEAD')
    def wrap(f):
        def inner(*args, **kwargs):
            cherrypy.response.headers['Allow'] = ', '.join(methods)
            if cherrypy.request.method not in methods:
                raise cherrypy.HTTPError(405)
            return f(*args, **kwargs):
        inner.exposed = True
        return inner
    return wrap

class Root:
    @allow()
    def index(self):
        return "Hello"

    cowboy_greeting = "Howdy"

    @allow()
    def cowboy(self):
        return self.cowboy_greeting

    @allow('PUT')
    def cowboyup(self, new_greeting=None):
        self.cowboy_greeting = new_greeting

내가 보게되는 또 다른 공통적 인 하나는 데이터베이스의 리소스에 해당하는 데이터를 찾는 것이고, 이는 동사에 관계없이 발생해야합니다.

def default(self, id, **kwargs):
    # 404 if no such beast
    thing = Things.get(id=id)
    if thing is None:
        raise cherrypy.NotFound()

    # ...and now switch on method
    if cherrypy.request.method == 'GET': ...

CherryPy는 당신을 위해 결정을 내리지 않으려하지만, 그것이 당신이 원하는 것이라면 쉽게 (한 줄짜리) 만듭니다.


Google에서이 문제가 발생하여 업데이트를 고려했습니다.

장고

방금 참고로, 이것은 클래스 기반 뷰로서 장고에서 지원됩니다. 제네릭 클래스 View 확장하고 get() , post() , put() 등과 같은 메서드를 추가 할 수 있습니다. 예 :

from django.http import HttpResponse
from django.views.generic import View

class MyView(View):

    def get(self, request, *args, **kwargs):
        return HttpResponse('Hello, World!')

dispatch() 부분은 this-

디스패치 (request, * args, ** kwargs)

뷰의 뷰 부분 - 요청 인수와 인수를 받아들이고 HTTP 응답을 반환하는 메서드입니다.

기본 구현은 HTTP 메소드를 검사하고 HTTP 메소드와 일치하는 메소드에 위임을 시도합니다. GET은 get (), post () 등 POST로 위임됩니다.

기본적으로 HEAD 요청은 get ()에 위임됩니다. GET과 다른 방법으로 HEAD 요청을 처리해야하는 경우 head () 메서드를 재정의 할 수 있습니다. 예제는 다른 HTTP 메소드 지원을 참조하십시오.

또한 기본 구현에서는 request, args 및 kwargs를 인스턴스 변수로 설정하므로보기의 모든 메소드는보기를 호출하기 위해 작성된 요청의 전체 세부 사항을 알 수 있습니다.

그럼 당신은 urls.py 에서 사용할 수 있습니다 -

from django.conf.urls import patterns, url

from myapp.views import MyView

urlpatterns = patterns('',
    url(r'^mine/$', MyView.as_view(), name='my-view'),
)

자세한 내용 .

체리 파이

CherryPy는 이제 이것을 지원합니다. 그들은 이것에 관한 전체 페이지 를 가지고있다.


이것은 DIY하기가 어렵지 않기 때문입니다. 각 클래스의 함수에 허용되는 동사 사전 만 있으면됩니다.

def dispatcher(someObject, request):
    try:
      return someObject.acceptedVerbs[request.method]()
    except:
      return http.HttpResponseNotAllowed(someObject.acceptedVerbs.keys())




web-frameworks