为什么 Django 和 CherryPy 本身不支持基于 HTTP 动词的调度?

2024-02-26

POST 到 URL 与 GET、DELETE 或 PUT 不同。这些行动有着根本的不同。然而,Django 的调度机制似乎忽略了它们。基本上,人们被迫要么完全忽略 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'])

我在网上找到了一些解决方案(这个片段 http://www.djangosnippets.org/snippets/436/用于基于动词的调度,或者这个装饰器 http://code.djangoproject.com/browser/django/trunk/django/views/decorators/http.py对于动词要求)不是很优雅,因为它们显然只是解决方法。

CherryPy 的情况似乎是一样的。据我所知,唯一能做到这一点的框架是 web.py 和 Google App Engine。

我认为这是 Web 框架的一个严重的设计缺陷。有人同意吗?或者这是基于我忽略的原因/要求而故意做出的决定?


我不能代表 Django,但在 CherryPy 中,您可以通过单个配置条目为每个 HTTP 动词拥有一个函数:

request.dispatch = cherrypy.dispatch.MethodDispatcher()

然而,我也见过一些不理想的情况。

一个例子是硬重定向,无论动词如何。

另一种情况是大多数处理程序只处理 GET。在这种情况下,有一千个页面处理程序都名为“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 试图不为您做出决定,但如果您想要的话,它会使其变得简单(一句台词)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Django 和 CherryPy 本身不支持基于 HTTP 动词的调度? 的相关文章

随机推荐