Ticket #4376: django.contrib.auth.decorators.diff

File django.contrib.auth.decorators.diff, 2.7 KB (added by steven.bethard@…, 17 years ago)

rewrite of django.contrib.auth.decorators to handle bound methods properly

  • decorators.py

     
    88    redirecting to the log-in page if necessary. The test should be a callable
    99    that takes the user object and returns True if the user passes.
    1010    """
    11     if not login_url:
    12         from django.conf import settings
    13         login_url = settings.LOGIN_URL
    14     def _dec(view_func):
    15         def _checklogin(request, *args, **kwargs):
    16             if test_func(request.user):
    17                 return view_func(request, *args, **kwargs)
    18             return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path())))
    19         _checklogin.__doc__ = view_func.__doc__
    20         _checklogin.__dict__ = view_func.__dict__
     11    def decorate(view_func):
     12        return _CheckLogin(view_func, self.test_func, self.login_url)
     13    return decorate
    2114
    22         return _checklogin
    23     return _dec
    24 
    25 login_required = user_passes_test(lambda u: u.is_authenticated())
    26 login_required.__doc__ = (
     15def login_required(view_func):
    2716    """
    2817    Decorator for views that checks that the user is logged in, redirecting
    2918    to the log-in page if necessary.
    3019    """
    31     )
     20    return _CheckLogin(view_func, lambda u: u.is_authenticated())
    3221
    3322def permission_required(perm, login_url=None):
    3423    """
     
    3726    """
    3827    return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url)
    3928
     29
     30class _CheckLogin(object):
     31    """
     32    Class that checks that the user passes the given test, redirecting to
     33    the log-in page if necessary. If the test is passed, the view function
     34    is invoked. The test should be a callable that takes the user object
     35    and returns True if the user passes.
     36
     37    We use a class here so that we can define __get__. This way, when a
     38    _CheckLogin object is used as a method decorator, the view function
     39    is properly bound to its instance.
     40    """
     41    def __init__(self, view_func, test_func, login_url=None):
     42        if not login_url:
     43            from django.conf import settings
     44            login_url = settings.LOGIN_URL
     45        self.view_func = view_func
     46        self.test_func = test_func
     47        self.login_url = login_url
     48       
     49    def __get__(self, obj, cls=None):
     50        view_func = self.view_func.__get__(obj, cls)
     51        return _CheckLogin(view_func, self.test_func, self.login_url)
     52   
     53    def __call__(self, request, *args, **kwargs):
     54        if self.test_func(request.user):
     55            return self.view_func(request, *args, **kwargs)
     56        path = quote(request.get_full_path())
     57        tup = self.login_url, REDIRECT_FIELD_NAME, path
     58        return HttpResponseRedirect('%s?%s=%s' % tup)
     59
Back to Top