【问题标题】:Django rest ModelViewSet multiple GET requests with different URLsDjango rest ModelViewSet 多个具有不同 URL 的 GET 请求
【发布时间】:2018-06-14 09:43:30
【问题描述】:

我必须模型:一个图书馆可以有很多书。

现在我有一个用于对特定图书馆中的图书执行 CRUD 的 URL:

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 编写另一个类或在现有 BookViewSet 中编写一个函数吗?这种情况下如何实现处理这两种 GET 方法?

【问题讨论】:

    标签: django django-rest-framework django-rest-viewsets


    【解决方案1】:

    您可以通过添加特殊方法 list_routedetail_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

    【讨论】:

    • 再次感谢您!现在我有了一个完整的工作示例,其中包含 ModelViewSet 的所有不同可能性:)
    【解决方案2】:

    list_routedetail_route 已贬值,它们与装饰器操作合并。

    https://www.django-rest-framework.org/community/3.8-announcement/#deprecations

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      相关资源
      最近更新 更多