[Django]-Django Rest Framework Filtering an object in get_queryset method

3👍

As the name of the method suggests, you need to return a queryset. Also, avoid iterating over a queryset if that’s not necessary. It’s better to do it in a single database hit. For complex queries, you can use the Q object.

from django.db.models import Q

# ...

    def get_queryset(self):
        user = self.request.user
        catalogs = Catalog.objects.filter(
                   Q(whitelist_users__in=[None, []]) | Q(whitelist_users__contains=user),
                   team__in=user.team_set.all())
                                                        
        return catalogs

Now I am not 100% sure the whitelist_users__contains=user will work since it depends on how you construct your JSON, but the idea is there, you will just need to adapt what it contains.

This will be much more effective than looping in python and will respect what get_queryset is meant for.

1👍

A simple solution that comes to mind is just creating a list of PKs and filtering again, that way you return a Queryset. Not the most efficient solution, but should work:

def get_queryset(self):
    pks = []
    user = self.request.user
    catalogs = Catalog.objects.filter(team__in=user.team_set.all())
    for catalog in catalogs:
        if catalog.whitelist_users == [] or catalog.whitelist_users == None:
            # catalog is open to whole team
            pks.append(catalog.pk)
        else:
            # catalog is private
            if user in catalog.whitelist_users:
                pks.append(catalog.pk)
    return Catalog.objects.filter(id__in=pks)
👤p14z

Leave a comment