0

I have 2 groups of users: Creator and Viewer. Creatorcan create, update, view and delete data, whileViewer` can only view data.

I can't understand how to implement them easily. Later on, I may have to allow certain crud for different models. I feel if groups can have custom acesss I will have full control, maybe a custom class?

I have separated the APIs now need to check if group matches then allow action on the API.

serializer.py

from rest_framework import serializers
from trackit_create.models import upload_status_image, track_info
from django.contrib.auth.models import Group

   

class StatusSerializer(serializers.ModelSerializer):
    
    class Meta:
        model=track_info
        fields = ('id','description','Manufacture','user','Cost','image')
        

views.py

# has option to create data 
class AssetCreator(mixins.CreateModelMixin, generics.ListAPIView,mixins.ListModelMixin):
    serializer_class =StatusSerializer
    authentication_classes= [TokenAuthentication]
    permission_classes = [permissions.IsAuthenticated]


    # def get(self, request, *args, **kwags):
    #     return self.get(request, *args, **kwags)

    def get_queryset(self):
        qs= track_info.objects.all()
        query= self.request.GET.get('q')
        if query is not None:
            qs=qs.filter(content__icontains=query)
            return qs
    
    def get_object(self):
        request = self.request
        passed_id = request.GET.get('id',None)
        queryset =self.get_queryset()

        if passed_id is not None:
            obj = get_object_or_404(queryset, id = passed_id)
            self.check_object_permissions(request, obj)        
        return obj       
        
    def post(self, request, *args, **kwags):
        return self.create(request, *args, **kwags)


# has permision to edit, delete data based on the 
class StatusAPIDetailView(mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.RetrieveAPIView):
    
      
    serializer_class = StatusSerializer
    authentication_classes= [TokenAuthentication]    
    permission_classes = [permissions.IsAuthenticated]    
    queryset= track_info.objects.all()
    lookup_field ='id'

  
    def put(self,request,*args,**kwargs):
        return self.update(request, *args, **kwargs)
    
    
    def delete(self,request,*args,**kwargs):
        return self.destroy (request, *args, **kwargs)
    
    def patch(self,request,*args,**kwargs):
        return self.update (request, *args, **kwargs)
    
    def perform_update(self, serializer):
        serializer.save(updated_by_user= self.request.user)
        
    def perform_destroy(self,request):
        if instance is not None:
            return instance.delete()        
        return None
    

class AssetGetlist(APIView):
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes= [TokenAuthentication]
    def get(self,request,format=None):
        qs = track_info.objects.all()
        query_set = Group.objects.filter(user = request.user)
        print ("fgfgf",query_set) # getting the group user is in 
        pm=print(query_set[0])
        #data={'grp':pm}           
        serializer= StatusSerializer(qs, many=True)
        return Response(serializer.data, status =status.HTTP_200_OK)

models.py

class track_info(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE)
    Entry_date = models.DateField(auto_now_add=True) 
    description = models.TextField(null=True, blank=True)
    image = models.ImageField(null=True, blank=True)
    Manufacture= models.CharField(max_length=100)
    Cost = models.IntegerField(null=True, blank=True)

I have refered to https://www.botreetechnologies.com/blog/django-user-groups-and-permission but I can't relate it to my code.

David Buck
  • 3,752
  • 35
  • 31
  • 35
Sourav Roy
  • 347
  • 3
  • 20

1 Answers1

2

You can create a custom permission class by extending Django Rest Framework BasePermission.

You'll need to implement has_permission method where you have access both the request and view objects. You can check request.user for being in right group and return True/False as appropriate.

Something like this:

from rest_framework.permissions import BasePermission

class CreatorOnly(BasePermission):
    def has_permission(self, request, view):
        if request.user.groups.filter(name='your_creator_group').exists() and request.method in YOUR_ALLOWED_METHODS:
           return True
        return False

And then add this into your view permissions list:

class AssetCreator(mixins.CreateModelMixin, generics.ListAPIView,mixins.ListModelMixin):
    ...
    permission_classes = [CreatorOnly]
Charnel
  • 4,222
  • 2
  • 16
  • 28
  • how to mention YOUR_ALLOWED_METHODS .. I have use used inbuild Safe_method but want to customize it with mine own . – Sourav Roy Jan 28 '20 at 13:00
  • @SouravRoy `YOUR_ALLOWED_METHODS` is just a tuple of method names (like 'GET', 'POST', 'HEAD', etc). You can allow `POST` for creators and only `GET` for viewers group. – Charnel Jan 28 '20 at 13:05