Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use request.user for model deserialization in django rest framework

Lets say i have a ToDo Model like this:

class ToDo(models.Model):
    user = models.ForeignKey(UserModel)
    text = models.CharField(max_length=255, blank=True)

And i'm using django rest framework for my API. Then i'll have this for the serializer:

class ToDoSerializer(serializers.ModelSerializer):
    class Meta:
        model = ToDo
        fields = ('text', 'id', 'user')

and this for the ViewSet:

class ToDoResponder(viewsets.ModelViewSet):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    model = ToDo
    def get_queryset(self):
        return ToDo.objects.filter(user=self.request.user)
    serializer_class = ToDoSerializer

As i'm using TokenAuthentication and get_queryset() the user can only see his own Todos. Unfortunately i can send ToDos and fake the user field so i could spam the ToDo List of another user. I don't want that.

How can i tell django-rest-framework to use request.user for specific fields like 'user' in the most DRY/Pythonic way? After all this is no exotic requirement and should be reused.

Thanks

like image 391
Harper04 Avatar asked Mar 10 '26 21:03

Harper04


1 Answers

In the drf doc http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions you can find a solution creating a new permission:

from rest_framework import permissions


class IsOwner(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        return obj.user == request.user

at this point you can use it in your ToDoResponder

permission_classes = (IsAuthenticated, IsOwner)

In the same page in your ToDoResponder:

def pre_save(self, obj):
    obj.user = self.request.user
    super(ToDoResponder, self).pre_save(obj)
like image 146
Andrea de Marco Avatar answered Mar 12 '26 10:03

Andrea de Marco



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!