Reputation: 5366
I have to Models: A Library can have many Books.
Right now I have a URL for performing CRUD on Books in a specific Library:
router.register(r'books/(?P<library_id>[0-9]+)', BookViewSet, base_name='books')
and corresponding view:
class BookViewSet(viewsets.ModelViewSet):
serializer_class = BookSerializer
def get_queryset(self):
genre_query = self.request.query_params.get('genre', None)
status_query = self.request.query_params.get('status', None)
author_query = self.request.query_params.get('author', None)
books = Book.objects.filter(which_library=self.kwargs.get('library_id'))
if genre_query:
books = books.filter(genre=genre_query)
if status_query:
books = books.filter(status=status_query)
if author_query:
books = books.filter(author=author_query)
return books
I originally did not use ModelViewSet instead I had functions with @api_view decorators, one of which was following (returning books added in last two weeks, I had a separate URL for this function as api/books//new_arrivals):
@api_view(['GET'])
def new_arrivals(request, library_id):
"""
List all new arrival books in a specific library
"""
d=timezone.now()-timedelta(days=14)
if request.method == 'GET':
books = Book.objects.filter(which_library=library_id)
books = books.filter(when_added__gte=d)
serializer = BookSerializer(books, many=True)
return Response(serializer.data)
While using ModelViewSets, how can I do it? Must I add another URL and then write another class for new_arrivals or write a function in existing BookViewSet? How to achieve handling those two GET methods in that case?
Upvotes: 4
Views: 3989
Reputation: 11
list_route
and detail_route
are depreciated and they are merged with decorator action.
https://www.django-rest-framework.org/community/3.8-announcement/#deprecations
Upvotes: 1
Reputation: 47364
You can extend traditional viewSet by adding special methods list_route
and detail_route
. With this decorators you can add new urls produced by ViewSet. In this case list_route
is more suitable:
from rest_framework.decorators import list_route
class BookViewSet(viewsets.ModelViewSet):
...
@list_route()
def new_arrivals(self, request):
books = self.get_queryset()
d=timezone.now()-timedelta(days=14)
books = books.filter(when_added__gte=d
serializer = self.get_serializer(books, many=True)
return Response(serializer.data)
This will add additional url to the viewSet: books/{library_id}/new_arrivals
.
Upvotes: 2