2

My ViewSet looks like this:

class ClientViewSet(viewsets.ModelViewSet):
    queryset = models.Client.objects.all()
    serializer_class = serializers.ClientSerializer

    def filter_queryset(self, queryset):
        return models.Client.objects.filter(**self.request.data)

    def get_queryset(self):
        return models.Client.objects.filter(owner=self.request.user)

The model looks like this:

class Client(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    name = models.CharField(max_length=100, blank=True, null=True)

    def __str__(self):
        return str(self.id)

So, I'm trying to filter clients so that only the current user's clients are presented to them. However, GET api/clients still returns all the clients of all users. What have I done wrong?

2
  • That is because you do not further process the queryset in the filter_queryset. Commented Aug 31, 2020 at 22:46
  • 1
    Use django-filter package, which is a very handy tool Commented Sep 1, 2020 at 3:14

1 Answer 1

2

That is because you do not further process the queryset in the filter_queryset. The filter_queryset is one of the next steps in the chain. You should thus further filter the queryset with:

class ClientViewSet(viewsets.ModelViewSet):
    queryset = models.Client.objects.all()
    serializer_class = serializers.ClientSerializer

    def filter_queryset(self, queryset):
        return queryset.filter(**self.request.data)

    def get_queryset(self):
        return models.Client.objects.filter(owner=self.request.user)

You however might want to take a look at the filter_backends [drf-doc]. This allows one to implement filters in a more elegant way. By using **self.request.data, you include potentially a security vulnerability, since the users can query not only on the model, but also on related model objects, and thus for example use binary search to determine fields that are sensitive.

Sign up to request clarification or add additional context in comments.

Comments

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.