1
from rest_framework.viewsets import ReadOnlyModelViewSet
from drf_renderer_xlsx.mixins import XLSXFileMixin
from drf_renderer_xlsx.renderers import XLSXRenderer
from .models import MyExampleModel
from .serializers import MyExampleSerializer

class MyExampleViewSet(XLSXFileMixin, ReadOnlyModelViewSet):
    serializer_class = MyExampleSerializer
    renderer_classes = [XLSXRenderer]
    filename = 'my_export.xlsx'

    def get_queryset(self):
        start_date = self.request.query_params.get('start_date', None)
        end_date = self.request.query_params.get('end_date', None)
        queryset = MyExampleModel.objects..filter(created__range=[start_date, end_date])
        Return queryset

        # What I want to do
        # If not queryset:
        #    Return Response({"message": "Exporting Fail"})
        

# Is there a way to check if queryset is None and return a Error Message instead of an empty Excel
# I think that I not allow return Response in the get_queryset function

Currently, I am trying to build a function to export excel file. I just want to know is there a way to check if the queryset is None and then I can return a Response({"message": "Exporting Fail, Empty"})

If you know where can I research it would help me a lot. Thank you so much

Sam Martin
  • 11
  • 1

1 Answers1

0

You should be doing the filtering in filter_queryset or get_queryset so what you already have is correct. But get_queryset has to return a queryset, not a Response object.

You will access the actual object in get_object method.


    def get_object(self):
        """
        Returns the object the view is displaying.

        You may want to override this if you need to provide non-standard
        queryset lookups.  Eg if objects are referenced using multiple
        keyword arguments in the url conf.
        """
        queryset = self.filter_queryset(self.get_queryset())

        # Perform the lookup filtering.
        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field

        assert lookup_url_kwarg in self.kwargs, (
            'Expected view %s to be called with a URL keyword argument '
            'named "%s". Fix your URL conf, or set the `.lookup_field` '
            'attribute on the view correctly.' %
            (self.__class__.__name__, lookup_url_kwarg)
        )

        filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
        obj = get_object_or_404(queryset, **filter_kwargs)

        # May raise a permission denied
        self.check_object_permissions(self.request, obj)

        return obj

If you don't want to raise a 404 if queryset is empty, you will have to first adjust those few final lines.

Then, as you can only retrieve and list in your view set, adjust those methods accordingly.


    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        if not instance:
            return Response({"message": "Exporting Fail"})
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

Or you don't alter get_object at all and handle 404

    def retrieve(self, request, *args, **kwargs):
        try:
            instance = self.get_object()
            serializer = self.get_serializer(instance)
            return Response(serializer.data)
        except Http404:
            return Response({"message": "Exporting Fail"})

but imo it's not a clean solution.

Tom Wojcik
  • 5,471
  • 4
  • 32
  • 44