Fata Express
Fata Express

Reputation: 1

How can I make only superusers to edit model

I have 2 models: Recipe and Ingridient and I want that only superusers will be able to edit model Ingridient, normal users can only view ingridients and are not able to edit them. Right now is set that way that if you are logged in you have all permissions, but I want that only superusers have ability to edit Ingridients and normal logged in users are able to add recipes (not able to edit ingridients).

#views.py

class ReceptViewRetrieveUpdateDestroy(generics.RetrieveUpdateDestroyAPIView):
    queryset = Recipe.objects.all()
    lookup_field = 'id'
    serializer_class = RecipeSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def delete(self, request, *args, **kwargs):
        try:
            id = request.data.get('id', None)
            response= super().delete(request, *args, **kwargs)

            if response.status_code == 204:
                from django.core.cache import cache
                cache.delete("{}".format(id))
                return response

        except Exception as e:
            return response({
                "Message":"Failed"
            }) 

    def update(self, request, *args, **kwargs):
        response = super().update(request, *args, **kwargs)
        if response.status_code == 200:
            mydata = response.data
    
            from django.core.cache import cache

            cache.set("ID :{}".format(mydata.get('id', None)),{
                'title':mydata["title"],
                'description':mydata["description"],
                'image':mydata["image"],
                'galery':mydata["galery"],
                'kitchen_type':mydata["kitchen_type"],
                'num_persons':mydata["num_persons"],
                'preparation_steps':mydata["preparation_steps"]
            })
           return response

class SestavinaViewRetrieveUpdateDestroy(generics.RetrieveUpdateDestroyAPIView):
    queryset = Ingridient.objects.all()
    lookup_field = 'id'
    serializer_class = IngridientSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def delete(self, request, *args, **kwargs):
        try:
            id = request.data.get('id', None)
            response= super().delete(request, *args, **kwargs)

            if response.status_code == 204:
                from django.core.cache import cache
                cache.delete("{}".format(id))
                return response

        except Exception as e:
            return response({
                "Message":"Failed"
            })   

    def update(self, request, *args, **kwargs):
        response = super().update(request, *args, **kwargs)
        if response.status_code == 200:
            mydata = response.data

            from django.core.cache import cache

            cache.set("ID :{}".format(mydata.get('id', None)),{
                'name':mydata["name"],
                'quantity':mydata["quantity"],
                'calories':mydata["calories"],
                'protein':mydata["protein"],
                'carbon':mydata["carbon"],
                'fiber':mydata["fiber"],
                'fat':mydata["fat"],
                'saturated_fat':mydata["saturated_fat"]
            })
            return response
        
class RecipeListView(generics.ListCreateAPIView):  
    model = Recipe
    serializer_class = RecipeSerializer
    queryset = Recipe.objects.all()
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

class IngridientsListView(generics.ListCreateAPIView):  
    model = Ingridient
    serializer_class = IngridientSerializer
    queryset = Ingridient.objects.all()
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

#models.py

class Ingridient(models.Model):
    name = models.CharField(default='', max_length=20)
    quantity = models.IntegerField(default=0)
    calories = models.IntegerField(default=0)
    protein = models.IntegerField(default=0)
    carbon = models.IntegerField(default=0)
    fiber = models.IntegerField(default=0)
    fat = models.IntegerField(default=0)
    saturated_fat = models.IntegerField(default=0)

    def __str__(self):
        return self.name

class Recipe(models.Model):
    title = models.CharField(default='', max_length=60)
    description = models.TextField(default='',max_length=1000)
    image = models.ImageField(default='',upload_to='pics', blank=True)
    galery = models.ImageField(default='', blank=True)
    kitchen_type = models.CharField(default='',max_length=35)
    num_persons = models.IntegerField(default=0)
    preparation_steps = models.TextField(default='')
    Ingridients = models.ManyToManyField(Ingridient)


    def __str__(self):
        return self.title

#serializers.py

class IngridientSerializer(serializers.ModelSerializer):
    class Meta:
       model = Ingridient
       fields = ('name', 'quantity', 'calories', 'protein', 'carbon', 'fiber', 'fat',         
       'saturated_fat')

class RecipeSerializer(serializers.ModelSerializer):
    Ingridients = IngridientSerializer(many=True)
    class Meta:
        model = Recipe
        fields = ('title', 'description', 'image', 'galery', 'kitchen_type', 'num_persons', 
        'preparation_steps', 'Ingridients')

Upvotes: 0

Views: 57

Answers (1)

AKX
AKX

Reputation: 169417

If you're willing to set up Django model permissions for your Ingredient model instead (i.e. add an "Ingredient Editors" group, and add all superusers to that group, then allow those users to edit Ingredients), you can use the DjangoModelPermissions permissions class instead of IsAuthenticatedOrReadOnly.

If you really do simply want to give all superusers write permissions, you can adapt DRF's IsAuthenticatedOrReadOnly permission class to something like

class IsAdminOrReadOnly(BasePermission):
    def has_permission(self, request, view):
        return bool(
            request.method in SAFE_METHODS or
            request.user and
            request.user.is_superuser
        )

and then use that permission class instead.

Upvotes: 2

Related Questions