title: Django custom decorator - function has no attribute get
body: <p>I'm trying to create my own decorator based on <a href="https://docs.djangoproject.com/en/1.11/topics/cache/#django.views.decorators.cache.cache_page" rel="nofollow noreferrer">@cache_page</a> decorator. My decorator should work exactly like <a href="https://docs.djangoproject.com/en/1.11/topics/cache/#django.views.decorators.cache.cache_page" rel="nofollow noreferrer">@cache_page</a> except when <code>slug</code> attribute of the view matches <code>request.user.userprofile</code> slug, then normally process the view and return not cached response</p>
  
  <p>Pseudocode:</p>
  
  <pre><code>def profile(request,slug):
      # if not request.user = User.objects.get(userprofile__slug=slug): 
      # return cache
      # else compute response and return it
  </code></pre>
  
  <p>My decorator:</p>
  
  <pre><code>def exclude_cache_for_request_user(*args, **kwargs):
      def exclude_cache_for_request_user_decorator(func):
          def func_wrapper(*fargs,**fkwargs):
              request = fargs[0]
              if request:
                  user = getattr(request,'user',None)
                  owner_slug = fkwargs.get('slug')
                  owner = User.objects.get(userprofile__slug=owner_slug)
                  if user==owner:
                      return func(*fargs, **fkwargs)
                  else:
                      if len(args) != 1 or callable(args[0]):
                          raise TypeError("cache_page has a single mandatory positional argument: timeout")
                      cache_timeout = args[0]
                      cache_alias = kwargs.pop('cache', None)
                      key_prefix = kwargs.pop('key_prefix', None)
                      if kwargs:
                          raise TypeError("cache_page has two optional keyword arguments: cache and key_prefix")
  
                      return decorator_from_middleware_with_args(CacheMiddleware)(
                          cache_timeout=cache_timeout, cache_alias=cache_alias, key_prefix=key_prefix
                      )
          return func_wrapper
      return exclude_cache_for_request_user_decorator
  </code></pre>
  
  <p>This works if user matches the slug. Otherwise, it raises:</p>
  
  <blockquote>
    <p>Exception Value:<br>
    'function' object has no attribute 'get'</p>
  </blockquote>
  
  <p>Full traceback:</p>
  
  <pre><code>File "/home/milano/.virtualenvs/beduenovenv/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
    41.             response = get_response(request)
  
  File "/home/milano/.virtualenvs/beduenovenv/local/lib/python2.7/site-packages/django/utils/deprecation.py" in __call__
    142.             response = self.process_response(request, response)
  
  File "/home/milano/.virtualenvs/beduenovenv/local/lib/python2.7/site-packages/django/middleware/clickjacking.py" in process_response
    32.         if response.get('X-Frame-Options') is not None:
  
  Exception Type: AttributeError at /profiles/detail/cingo/
  Exception Value: 'function' object has no attribute 'get'
  </code></pre>
  
  <p>Do you know where is the problem? The best would be if there were caching for user and other users separately. So 2 caches for this view.</p>
  
  <p><strong>EDIT:</strong> This is an original <code>@cache_page</code> decorator</p>
  
  <pre><code>def cache_page(*args, **kwargs):
      """
      Decorator for views that tries getting the page from the cache and
      populates the cache if the page isn't in the cache yet.
  
      The cache is keyed by the URL and some data from the headers.
      Additionally there is the key prefix that is used to distinguish different
      cache areas in a multi-site setup. You could use the
      get_current_site().domain, for example, as that is unique across a Django
      project.
  
      Additionally, all headers from the response's Vary header will be taken
      into account on caching -- just like the middleware does.
      """
      # We also add some asserts to give better error messages in case people are
      # using other ways to call cache_page that no longer work.
      if len(args) != 1 or callable(args[0]):
          raise TypeError("cache_page has a single mandatory positional argument: timeout")
      cache_timeout = args[0]
      cache_alias = kwargs.pop('cache', None)
      key_prefix = kwargs.pop('key_prefix', None)
      if kwargs:
          raise TypeError("cache_page has two optional keyword arguments: cache and key_prefix")
  
      return decorator_from_middleware_with_args(CacheMiddleware)(
          cache_timeout=cache_timeout, cache_alias=cache_alias, key_prefix=key_prefix
      )
  </code></pre>