Search code examples
pythondjangopython-decorators

custom decorator for class viewsets


I have a view set like this

class NeProjectsViewSet(viewsets.ViewSet):

   def list(self, request,org_unique_id):
       ''' something '''

   def create(self, request,org_unique_id):
       ''' something '''

   def retrieve(self):
       ''' something '''

   def update(self, request, pk):
       ''' something '''

   def partial_update(self, request):
       ''' something '''

   def destroy(self, request):
       ''' something '''

and i've a method like this

def check_session(self,request):
    current_datetime = datetime.now()
    if ('last_login' in request.session):
        last = (current_datetime - datetime.strptime(request.session['last_login'], "%Y-%m-%d %H:%M:%S.%f")).seconds
        if last > base.SESSION_IDLE_TIMEOUT:
            del request.session['token']
            raise ValueError('Session Expired')
    else:
        request.session['last_login'] = str(current_datetime)
    return (request.session['token'] == request.META['HTTP_AUTHORIZATION'])

to validate session for every request, for that i need to call this method before every method in the viewset. I read somewhere writing custom decorator is better way, so how to implement custom decorator for my view set to check session for request


Solution

  • Assuming you are using DRF.

    I think you are going in wrong direction. If this is part of your permission layer you should just add custom permission class to your viewset

    http://www.django-rest-framework.org/api-guide/permissions/

    from rest_framework import permissions
    
    class ValidateSession(permissions.BasePermission):
        """
        Validate session expiration
        """
    
        def has_permission(self, request, view):
            current_datetime = datetime.now()
            if ('last_login' in request.session):
                last = (current_datetime - datetime.strptime(request.session['last_login'], "%Y-%m-%d %H:%M:%S.%f")).seconds
                if last > base.SESSION_IDLE_TIMEOUT:
                    del request.session['token']
                    return False
            else:
                request.session['last_login'] = str(current_datetime)
            return (request.session['token'] == request.META['HTTP_AUTHORIZATION'])
    

    And then add it like this

    class NeProjectsViewSet(viewsets.ViewSet):
        permission_classes = (ValidateSession,)
        ...
    

    Assuming you're using plain django

    from django.contrib.auth.mixins import AccessMixin
    
    class ValidateSessionMixin(AccessMixin):
        """
        Validate session
        """
        def has_permission(self):
            current_datetime = datetime.now()
            request = self.request
            if ('last_login' in request.session):
                last = (current_datetime - datetime.strptime(request.session['last_login'], "%Y-%m-%d %H:%M:%S.%f")).seconds
                if last > base.SESSION_IDLE_TIMEOUT:
                    del request.session['token']
                    return True
            else:
                request.session['last_login'] = str(current_datetime)
            return (request.session['token'] == request.META['HTTP_AUTHORIZATION'])
    
        def dispatch(self, request, *args, **kwargs):
            if not self.has_permission():
                return self.handle_no_permission()
            return super(ValidateSessionMixin, self).dispatch(request, *args, **kwargs)
    

    And apply this mixin like this

    class NeProjectsViewSet(ValidateSessionMixin, viewsets.ViewSet):
        ...