DRF Pattern: Query Elements which Belongs to One Element

20th August 2020 at 2:19pm
Django REST Framework: Pattern

查询某一元素下的一批元素。比如:

  • 查询某个作者写的图书
  • 查询某个班级的学生

对于使用 ModelViewSet 的情况,可以用 自定义动作 来实现。自定义动作即是指,除了 ModelViewSet 默认提供 create、retrieve、update、destroy 及 list 动作外,自定义新的动作。比如下面这个例子,books 函数实现了查询某一作者下的图书:

class BookAuthorViewSet(viewsets.ModelViewSet):
    queryset = BookAuthor.objects.all()
    serializer_class = BookAuthorSerializer

    @action(methods=['GET'], detail=True)    # 1
    def books(self, request, pk=None):
        try:
            author = BookAuthor.objects.get(id=pk)
        except BookAuthor.DoesNotExist:
            return Response({"error": "Author not found."}, status=status.HTTP_404_NOT_FOUND)

        books = author.book_set.order_by(
            F('publication_year').desc(nulls_last=True),
            F('publication_month').desc(nulls_last=True),
            F('publication_day').desc(nulls_last=True),
        )
                
        page = self.paginate_queryset(books)
        if page is not None:
                    # 2
            serializer = BookSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        else:
                    # 3
            serializer = BookSerializer(books, many=True)
            return Response(serializer.data)

代码解释:

  1. detail=True 表示是针对单个元素而不是列表的查询
  2. 如果 page 非 None,表示该项目 启用了分页,因此输出分页的结果;否则
  3. 输出完整的内容