3

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

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks that should work but i am still looking for another solution since i'd like to use request.user as the default value for user so the client don't has to send the user id.
Exactly what i want! One note: i had to remove 'user' from the fields list in the serializer otherwise pre_save() will not be called
You could add editable=False to user = models.ForeignKey(UserModel) if a ToDo Entry can't change the owner
that does not work for me. neither for this guy groups.google.com/forum/#!topic/django-rest-framework/…
Did you try with user = models.ForeignKey(UserModel, blank=True)?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.