问题描述
发布到URL不同于获取,删除或放置URL。这些动作从根本上是不同的。但是,Django似乎在其调度机制中忽略了它们。基本上,人们被迫要么完全忽略HTTP动词,要么在每个视图上都这样做:
It's not the same to POST to an URL than to GET it, DELETE it or PUT it. These actions are fundamentally different. However, Django seems to ignore them in its dispatch mechanism. Basically, one is forced to either ignore HTTP verbs completely or do this on every view:
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'])
我在网络上为此找到的一些解决方案(为动词基于调度,或作动词
The few solutions I have found for this in the web (this snippet for verb-based dispatch, or this decorator for verb requirement) are not very elegant as they are clearly just workarounds.
CherryPy的情况似乎是相同的。我知道唯一可以做到这一点的框架是web.py和Google App Engine。
The situation with CherryPy seems to be the same. The only frameworks I know of that get this right are web.py and Google App Engine's.
我认为这是Web框架的严重设计缺陷。有人同意吗?还是基于我忽略的原因/要求的故意决定?
I see this as a serious design flaw for a web framework. Does anyone agree? Or is it a deliberate decision based on reasons/requirements I ignore?
推荐答案
我不能代表Django,但是在CherryPy中,您可以为每个HTTP动词使用一个配置条目提供一个功能:
I can't speak for Django, but in CherryPy, you can have one function per HTTP verb with a single config entry:
request.dispatch = cherrypy.dispatch.MethodDispatcher()
但是,我发现有些情况是不希望的。
However, I have seen some situations where that's not desirable.
一个示例将是与动词无关的硬重定向。
One example would be a hard redirect regardless of verb.
另一种情况是大多数处理程序仅处理GET。在这种情况下,成千上万个名为 GET的页面处理程序尤其令人讨厌。用修饰符表示要比用函数名来表示更漂亮:
Another case is when the majority of your handlers only handle GET. It's especially annoying in that case to have a thousand page handlers all named 'GET'. It's prettier to express that in a decorator than in a function name:
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
我看到的另一种常见现象是查找与数据库中资源相对应的数据,该值应与动词无关:
Another common one I see is looking up data corresponding to the resource in a database, which should happen regardless of verb:
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尝试不为您做出决定,但如果您想要的话,则使其轻松(单线)。
CherryPy tries to not make the decision for you, yet makes it easy (a one-liner) if that's what you want.
这篇关于为什么Django和CherryPy不本地支持基于HTTP动词的调度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!