如何在没有路由的情况下缓存视图方法?

时间:2014-04-18 22:18:57

标签: django caching memcached

我正在尝试在我的代码中测试缓存。我使用memcached作为后端。我将CACHE配置设置为使用'basic'下的memcached。没有直接路由到get_stuff方法。这是我的代码:

我有一个看起来像

的视图
from .models import MyModel
from django.views.decorators.cache import cache_page


class MyView(TemplateView):
""" Django view ... """ 

template_name = "home.html"

@cache_page(60 * 15, cache="basic")
def get_stuff(self):  # pylint: disable=no-self-use
    """ Get all ... """
    return MyModel.objects.filter(visible=True, type=MyModel.CONSTANT)

def get_context_data(self, **kwargs):
    context = super(MyView, self).get_context_data(**kwargs)
    stuffs = self.get_stuff()
    if stuffs:
        context['stuff'] = random.choice(stuffs)
    return context

我也有一个看起来像

的测试
from django.test.client import RequestFactory
from xyz.apps.appname import views


class MyViewTestCase(TestCase):
""" Unit tests for the MyView class """

def test_caching_get_stuff(self):
    """ Tests that we are properly caching the query to get all stuffs """
    view = views.MyView.as_view()
    factory = RequestFactory()
    request = factory.get('/')
    response = view(request)
    print response.context_data['stuff']

当我运行测试时,我收到此错误:

Traceback (most recent call last):
File "/path/to/app/appname/tests.py", line 142, in test_caching_get_stuff
response = view(request)
File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py", line 87, in dispatch
return handler(request, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py", line 154, in get
context = self.get_context_data(**kwargs)
File "/path/to/app/appname/views.py", line 50, in get_context_data
stuffs = self.get_stuff()
File "/usr/local/lib/python2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view
result = middleware.process_request(request)
File "/usr/local/lib/python2.7/site-packages/django/middleware/cache.py", line 134, in process_request
if not request.method in ('GET', 'HEAD'):
AttributeError: 'MyView' object has no attribute 'method'

导致此问题的原因是什么?如何解决此问题?我是Python和Django的新手。

2 个答案:

答案 0 :(得分:1)

您能否在MIDDLEWARE_CLASSES中展示settings.py的内容?我查看了出现错误的代码,并指出FetchFromCacheMiddleware必须是MIDDLEWARE_CLASSES中的最后一块中间件。我想知道这是否会导致你的问题。

相关文档here

答案 1 :(得分:0)

我认为问题在于cache_page装饰器用于视图函数,而不是用于装饰基于类的视图的方法。视图函数将'request'作为它们的第一个参数,如果你看一下traceback,你可以看到实际上错误是由于你试图装饰的函数的第一个参数不是一个请求而是'self'(即,错误中引用的MyView对象。

我不确定cache_page装饰器是否或如何用于基于类的视图,虽然文档中的this page建议在URLconf中使用它,我想你可以包装ViewClass的返回.as_view以类似的方式。如果你试图在缓存中包装的东西不是一个正确的视图,而是某种实用函数,你应该放弃使用函数内部的更多手动lower-level cache API(而不是装饰器)。 / p>