Search code examples
pythondjangodecoratorpython-decorators

What's wrong with my?


I have a problem with decorator. I'm trying to write my own decorator with optional argument.

This is how its done now:

def CheckPremissions(manager=1):
    def wrap(func):
        def wrapper(request, *args, **kwargs):
            if request.user.is_anonymous():
                return HttpResponseRedirect(reverse('login'))

            logged_user = getRelatedWorker(request.user)

            if (logged_user == None):
                return HttpResponseRedirect('accounts/no_worker_error.html')

            if self.manager != 0:
                try:
                    dzial = Dzial.objects.get(kierownik=logged_user)
                except Dzial.DoesNotExist:
                    isManager = False
                else:
                    isManager = True

                if not isManager:
                    return HttpResponseRedirect('accounts/denied_logged.html')

            return func(request, *args, **kwargs)
        return wrapper
    return wrap

Code is looking good (for me), but when I use a decorator, I'm getting following error:

Environment:

    Request Method: GET
    Request URL: http://127.0.0.1:8080/applications/show

    Django Version: 1.4.1
    Python Version: 2.7.3


Traceback:
    File "/home/marcin/projekt/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
      188.                 response = middleware_method(request, response)
    File "/home/marcin/projekt/lib/python2.7/site-packages/django/middleware/common.py" in process_response
      94.         if response.status_code == 404:

    Exception Type: AttributeError at /applications/show
    Exception Value: 'function' object has no attribute 'status_code'

What am I doing wrong?


Solution

  • I suspect you are applying the decorator incorrectly. You need to call it to specify the manager parameter:

    @CheckPremissions()
    def someview(request):
        pass
    

    or to specify it explicitly:

    @CheckPremissions(manager=0)
    def someview(request):
        pass
    

    You have a different problem in your decorator as well; you refer to self.manager in the code:

    if self.manager != 0:
    

    but this is no instance, and there is no self parameter. I think you meant:

    if manager:
    

    (where you can test for the variable to be non-zero by treating it as a boolean). Oh, and you may want to fix the spelling of the decorator; you probably meant CheckPermissions instead. :-)