django Rest Framework – ViewSet with custom ListView and URL parameters… here is a solution to the problem.
django Rest Framework – ViewSet with custom ListView and URL parameters
I have the following settings:
I would like to list all holidays for a specific year. That’s why I omitted the default ListView and implemented my own ListView 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 value /holiday/year/, I get the results for that year.
But when I try to pass a parameter, I get a 404. The 404 page (in Debug mode) even showed 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 documentation unfortunately this aspect is not covered.
Any idea why my route to holiday/year/2017
didn’t work?
Solution
Ok, my workaround is to use 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 opinion:
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)
Website:
/api/v1/holiday/?year=2016