whoisearth
whoisearth

Reputation: 4170

DRF - limit objects returned to owner

I have a model

class Widget(models.Model):
    title = models.CharField(max_length=100)
    description = models.CharField(max_length=1024)
    username = models.CharField(max_length=50)
    code = models.CharField(max_length=1024)
    owner = models.ForeignKey('MyappUser', related_name='Myapp_owner')
    list = models.ForeignKey('WidgetList')

What I want to be able to do is when calling a specific view -

class WidgetList(generics.ListCreateAPIView):
    queryset = Widget.objects.all()
    serializer_class = WidgetSerializer
    filter_class = WidgetFilter

I only want the widgets owned by the user logged in.

My current filter is -

class WidgetFilter(django_filters.FilterSet):
    owner = django_filters.NumberFilter(name="owner", lookup_type="exact")
    list = django_filters.NumberFilter(name="list", lookup_type="exact")

    class Meta:
        model = Widget
        fields = ['owner', 'list']

Right now I have to do /api/widgets/?owner=3&list=5

But that doesn't prevent another user from viewing the widget.

I had previously been doing it using the following but it breaks my ability to do a filter class -

class WidgetList(generics.ListCreateAPIView):
    queryset = Widget.objects.all()
    serializer_class = WidgetSerializer


    def get(self, request):
        if request.user:
            queryset = self.get_queryset().filter(owner=request.user)
            for object in queryset:
                object.code = decrypt_code(masterkey,
                                                   personalkey,
                                                   object.code)
        else:
            queryset = self.get_queryset()

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = WidgetSerializer(queryset, many=True)
        return Response(serializer.data)

What I want to be able to do is if I have a list like this -

Jane
Widget 1
Widget List ABC

Jane
Widget 2
Widget List DEF (which is 3)

Mike (which is 3)
Widget 3
Widget List ABC (which is 5)

Alfred
Widget 4
Widget List ABC

if I do /api/widgets/?list=5 if I'm logged in as Mike I only want to see Widget 3

Upvotes: 0

Views: 691

Answers (1)

masnun
masnun

Reputation: 11906

From the docs:

Note that you can use both an overridden .get_queryset() and generic filtering together, and everything will work as expected.

So I would do something like:

class WidgetList(generics.ListCreateAPIView):
    queryset = Widget.objects.all()
    serializer_class = WidgetSerializer
    filter_class = WidgetFilter


    def get_queryset(self):
        owner = self.request.user
        return super(WidgetList, self).get_queryset().filter(owner=request.user)

I didn't manage to test the code however my expectation is that get_queryset would only return the entries filtered by owner. So it will not contain entries from other users.

Upvotes: 3

Related Questions