5

I read on DRF doc that you can filter againt query parameters by overriding .get_queryset(). I am looking for the best practice, on what to return, in case the filters are incorrect and where to return an error message.

The doc I referred to is here And I include the source code below

class PurchaseList(generics.ListAPIView):
    serializer_class = PurchaseSerializer

    def get_queryset(self):
        """
        Optionally restricts the returned purchases to a given user,
        by filtering against a `username` query parameter in the URL.
        """
        queryset = Purchase.objects.all()
        username = self.request.query_params.get('username', None)
        if username is not None:
            queryset = queryset.filter(purchaser__username=username)
        return queryset

Thank you for your help

Solal
  • 611
  • 2
  • 9
  • 26
  • Don't return an error and ignore if the key is not correct. If you are afraid it'll return too much content, use pagination. – Linovia Feb 13 '19 at 10:07

2 Answers2

7

If your API is strict and you need to send some message about the bad filters you can raise an error so DRF knows how to handle it (docs) For example:

from rest_framework.exceptions import ValidationError

class PurchaseList(generics.ListAPIView):
    serializer_class = PurchaseSerializer

    def get_queryset(self):
      ...
      if error:
        raise ValidationError(detail='Invalid Params')
5

You can do this

from rest_framework import status

class PurchaseList(generics.ListAPIView):
    serializer_class = PurchaseSerializer
    def get_queryset(self):
        try:
            """
            Optionally restricts the returned purchases to a given user,
            by filtering against a username query parameter in the URL.
            """
            queryset = Purchase.objects.all()
            username = self.request.query_params.get('username', None)
            if username is not None:
                    queryset = queryset.filter(purchaser__username=username)
            return queryset
        except:
            return None

    def get(self, request):
        try:
           data=view_serializer(self.get_queryset(),many=True).data
           context = {
               "data" : data,
               "message" : "Contents returned successfully",
               "success" : True
               }
           return Response(context, status=status.HTTP_200_OK)
        except Exception as error:
           context = {'error': str(error), 'success': "false", 'message': 'Failed To Get contents.'}
           return Response(context, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Ab1gor
  • 398
  • 3
  • 19
  • Thanks for the answer. However returning a 400 throw server error. – Solal Feb 21 '19 at 10:14
  • Can you post me the error? or show screenshot of it? – Ab1gor Feb 22 '19 at 09:20
  • 1
    It returns `The response content must be rendered before it can be iterated over.` After searching this I found an answer to my issue [here](https://stackoverflow.com/questions/45848057/django-rest-error-when-creating-a-custom-response-message) – Solal Feb 22 '19 at 09:27
  • I have updated the answer. Now it's correct. You can mark it correct so that others can find it helpful. And thanks for pointing out that we can't return Response inside get_queryset() – Ab1gor Feb 22 '19 at 10:36