Search code examples
djangodjango-rest-frameworkdjango-querysetdjango-filter

Django Rest Framework, filter by name


I'm trying to create a filter by username, but django nonstop requires id from me. What is repair here?

class FavoriteList(generics.ListCreateAPIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsCurrentUserOwnerOrHidden]
    queryset = Favorite.objects.all()
    serializer_class = FavoritesSerializer
    name = 'favorite-list'

def perform_create(self, serializer):
    serializer.save(owner=self.request.user)

def filter_queryset(self, queryset):
    owner_name = self.request.query_params.get('owner', None)
    if owner_name is not None:
        queryset = queryset.filter(owner=owner_name)
    return queryset

localhost/favorite?owner=1 is working but loclahost/favorite?owner=admin don't


Solution

  • It works that way because .filter method for ForeignKey searches by id. To search by username field you have to use proper lookup:

    queryset.filter(owner__username=owner_name)
    

    You can separate that values or I might suggest smart try/except:

    def filter_queryset(self, queryset):
        owner_name = self.request.query_params.get('owner', None)
        if owner_name is not None:
    
            try:
                owner_id = int(owner_name)
            except ValueError:
                owner_id = None
    
            if owner_id:
                queryset = queryset.filter(owner=owner_id)
            else:
                queryset = queryset.filter(owner__username=owner_name)
    
        return queryset
    

    With above solution you can pass either object's id or username attribute as a GET parameter.