Django rest ModelViewSet 多个具有不同 URL 的 GET 请求
Django rest ModelViewSet multiple GET requests with different URLs
我必须建模:一个图书馆可以有很多书。
现在我有一个 URL 用于对特定图书馆中的图书执行 CRUD:
router.register(r'books/(?P<library_id>[0-9]+)', BookViewSet, base_name='books')
和相应的视图:
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
我最初没有使用 ModelViewSet,而是使用了带有 @api_view 装饰器的函数,其中之一如下(返回过去两周添加的书籍,我有一个单独的 URL 这个函数如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)
在使用ModelViewSets时,我该怎么做?我是否必须添加另一个 URL 然后为 new_arrivals 编写另一个 class 或在现有 BookViewSet 中编写一个函数?在那种情况下如何实现处理这两个 GET 方法?
您可以通过添加特殊方法 list_route
和 detail_route
来扩展传统的 viewSet。使用此装饰器,您可以添加由 ViewSet 生成的新 url。这种情况下list_route
更合适:
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)
这将向视图集添加额外的 url:books/{library_id}/new_arrivals
。
list_route
和 detail_route
已折旧并与装饰器操作合并。
https://www.django-rest-framework.org/community/3.8-announcement/#deprecations
我必须建模:一个图书馆可以有很多书。
现在我有一个 URL 用于对特定图书馆中的图书执行 CRUD:
router.register(r'books/(?P<library_id>[0-9]+)', BookViewSet, base_name='books')
和相应的视图:
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
我最初没有使用 ModelViewSet,而是使用了带有 @api_view 装饰器的函数,其中之一如下(返回过去两周添加的书籍,我有一个单独的 URL 这个函数如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)
在使用ModelViewSets时,我该怎么做?我是否必须添加另一个 URL 然后为 new_arrivals 编写另一个 class 或在现有 BookViewSet 中编写一个函数?在那种情况下如何实现处理这两个 GET 方法?
您可以通过添加特殊方法 list_route
和 detail_route
来扩展传统的 viewSet。使用此装饰器,您可以添加由 ViewSet 生成的新 url。这种情况下list_route
更合适:
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)
这将向视图集添加额外的 url:books/{library_id}/new_arrivals
。
list_route
和 detail_route
已折旧并与装饰器操作合并。
https://www.django-rest-framework.org/community/3.8-announcement/#deprecations