Question

I'm have a generic view where I use the login_required decorator in the urls.py file, like this:

(r'^my-url/$', login_required(ListView.as_view())),

Now, I would like to use the vary_on_headers decorator for this url, but I can't get it working.

I've tried:

(r'^my-url/$', vary_on_headers(login_required(ListView.as_view()),'HTTP_X_REQUESTED_WITH'))

but I got the following error during my tests:

response = self.client.get('/my-url/', HTTP_X_REQUESTED_WITH='XMLHttpRequest')
  File "/lib/python2.6/site-packages/django/test/client.py", line 439, in get
    response = super(Client, self).get(path, data=data, **extra)
  File "/lib/python2.6/site-packages/django/test/client.py", line 241, in get
    return self.request(**r)
  File "/lib/python2.6/site-packages/django/core/handlers/base.py", line 178, in get_response
    response = middleware_method(request, response)
  File "/lib/python2.6/site-packages/django/middleware/common.py", line 94, in process_response
    if response.status_code == 404:
AttributeError: 'function' object has no attribute 'status_code'

If I try:

(r'^my-url/$', login_required(vary_on_headers(MyProductsView.as_view(),'HTTP_X_REQUESTED_WITH'))),

but I get the following error now:

response = self.client.get('/my-url/', HTTP_X_REQUESTED_WITH='XMLHttpRequest')
  File "/lib/python2.6/site-packages/django/test/client.py", line 439, in get
    response = super(Client, self).get(path, data=data, **extra)
  File "/lib/python2.6/site-packages/django/test/client.py", line 241, in get
    return self.request(**r)
  File "/lib/python2.6/site-packages/django/core/handlers/base.py", line 178, in get_response
    response = middleware_method(request, response)
  File "/lib/python2.6/site-packages/django/contrib/sessions/middleware.py", line 26, in process_response
    patch_vary_headers(response, ('Cookie',))
  File "/lib/python2.6/site-packages/django/utils/cache.py", line 133, in patch_vary_headers
    if response.has_header('Vary'):
AttributeError: 'function' object has no attribute 'has_header'

Any ideas on what could be happening and how to solve this problem?

Was it helpful?

Solution

You have mixed up the view function that you are decorating with the header arguments for the vary_on_headers decorator.

Try the following:

(r'^my-url/$', vary_on_headers('X_REQUESTED_WITH')(login_required(ListView.as_view())),

Or, if you want to apply the decorators the other way around:

(r'^my-url/$', login_required(vary_on_headers('X_REQUESTED_WITH')(ListView.as_view())),

OTHER TIPS

If you have a custom view class (or base class), instead of decorating every call to as_view(), you can use method_decorator to decorate the get method of your view, or even dispatch:

from django.utils.decorators import method_decorator

@method_decorator(vary_on_headers('X-Requested-With'))
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
    return super(MyView, self).dispatch(*args, **kwargs)

You could also create a mixin that does that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top