change an object with ModelViewSet

142 Views Asked by At

im building a project with DRF and im trying to understand how the modelviewset is working, im sending a url like this: localhost/do_somthing/object_id/ and route it with :

router.register('do_somthing', views.do_somthing, basename='do_somthing')

the view is:

class do_somthing_View(viewsets.ModelViewSet):
    serializer_class = ObjectSerializer
    permission_classes = [permissions.IsAuthenticated]
    queryset = Object.objects.all()
    http_method_names = ['get']

    def get_queryset(self):
        obj= Object.objects.get(id=self.kwargs['pk'])
        user = self.request.user
        if user == obj.user:
            obj.att= True
            obj.save
            return self.queryset
        else:
            None

the object model looks like this:

class Object(models.Model):
    user= models.ForeignKey(User, on_delete=models.PROTECT, related_name="realted_user")
    name= models.CharField(max_length=50)
    att= models.BooleanField(default=False)

    def __str__(self):
        return self.name

the problem is that the att never changes and still set to False is there any way better i can get to change the attribute and return the object BTW ive tried to return an unauthorized response when its not that user but i cant return a response if someone can please help me or can even suggest a better way to do that that would help me alot thanks

i am trying to present an object and when its presented by the correct user change an attribute of that object

1

There are 1 best solutions below

2
On

first of all you need to call the save method and change obj.save to obj.save() and don't forget to add params in the path for kwargs. I advise overriding get or update for this not get_queryset for returning unauthorized I strongly recommend creating a custom permission class inheriting from IsAuthenticated and overriding has_object_permission it will do the entire thing for you it makes sure it is user's it will return 403 if it's not(that happens in drf default exception handler) if you don't want to do that and still want a 403 response do this:

from rest_framework.exceptions import PermissionDenied

class do_somthing_View(viewsets.ModelViewSet):
    ...

    def get_queryset(self):
        ...
        if user == obj.user:
           ...
        else:
            raise PermissionDenied("some proper message")

I still STRONGLY advise you to use a custom permission class and move logic part out of get_queryset