Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django Rest Framework - ViewSet with custom list view and URL parameter

I have the following setup:

I want to list all holidays of a specific year. That's why I leave out the default list view and implement my own like this:

class HolidayViewSet(mixins.RetrieveModelMixin, GenericViewSet):
@list_route()
def year(self, request, year=get_today().year):
    public_holidays = self.get_queryset().filter(date__year=year)
    page = self.paginate_queryset(public_holidays)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)
    serializer = self.get_serializer(public_holidays, many=True)
    return Response(serializer.data)

If I use the default /holiday/year/ I get a result for the current year.

But whe I try to pass a parameter, I'll get a 404. The 404 page (in debug mode) even shows me the correct URL pattern:

api/v1/ ^holiday/year/$ [name='holiday-year']
api/v1/ ^holiday/year\.(?P<format>[a-z0-9]+)/?$ [name='holiday-year']

In the documentation this aspect is unfortunately not covered.

Any ideas why my route to holiday/year/2017 is not working?

like image 918
Ron Avatar asked Nov 24 '25 19:11

Ron


1 Answers

Ok, my workaround is using django-filter.

My filter:

class HolidayFilter(filters.FilterSet):
    """
    This filter can be used to filter holidays by different values in API views or viewsets.
    See http://django-filter.readthedocs.io/en/1.1.0/guide/rest_framework.html
    """
    year = filters.NumberFilter(name='date', lookup_expr='year')

    class Meta:
        model = Holiday
        fields = ['date']

My viewset:

class HolidayListViewSet(ModelViewSet):

    def list(self, request, *args, **kwargs):
        # Apply filters
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        # Pagination
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        # Serializer
        serializer = self.get_serializer(queryset, many=True)
        # Response
        return Response(serializer.data)

The URL:

/api/v1/holiday/?year=2016
like image 94
Ron Avatar answered Nov 28 '25 16:11

Ron



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!