我最近将我的一个 Django 项目中的所有视图迁移到了新的基于类的视图。对于经典的基于函数的 Django 视图,django.views.decorators.http.condition
如果存在与您指定的条件匹配的缓存副本,则可以使用一个方便的装饰器绕过整个视图处理。我在文档和源代码中到处搜索,但找不到新的基于类的视图的任何实现。
所以我的问题是:您如何建议我为基于类的视图实现条件视图处理?
看起来这个问题还没有一个很好的答案。对于只设置函数属性(例如csrf_exempt
)的装饰器,将它们应用于视图类的dispatch
方法就足够了,但这显然不适用于condition
装饰器,因为它们希望第一个函数参数是请求对象而不是self
.
您可以通过两种方式实现这一目标:
将装饰器应用于生成的视图函数。通用视图功能实际上归结为一种从类构建视图函数的方式,因此延迟应用装饰器可能是一种选择。像这样的东西:
f = ViewClass.as_view()
f = condition(...)(f)
这样做的缺点是您无法从传递给condition
装饰器的函数中访问视图类。如果您as_view
在 urlconf 中调用该方法,也不是很方便。
委托给一个简单的函数,您可以在视图的dispatch
方法中应用装饰器。像这样的东西:
def dispatch(self, request, *args, **kwargs):
@condition(...)
def _dispatch(request, *args, **kwargs):
return super(ViewClass, self).dispatch(request, *args, **kwargs)
return _dispatch(request, *args, **kwargs)
这样做的好处是您可以在应用装饰器时访问视图类实例,因此您可以将实例方法用于缓存验证功能。缺点是每次调用视图时都会运行装饰器,但这对于这个特定的装饰器来说似乎不是问题。
虽然这两种解决方案都有其问题,所以也许值得提交一个错误报告或在 django-users 邮件列表中询问如何最好地结合这两个概念。
您可以使用以下内容:
def conditional(**kwargs):
'''A wrapper around :func:`django.views.decorators.http.condition` that
works for methods (i.e. class-based views).
'''
from django.views.decorators.http import condition
from django.utils.decorators import method_decorator
return method_decorator(condition(**kwargs))
缓存是一个复杂的问题,但最近的趋势(服务器中的数据/片段缓存以及浏览器中的资产缓存)表明最好不要花时间解决缓存失效问题,而只是做在这篇文章中描述:
http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works
这种技术应用于 Django 的真实示例: