我有两种模式:
class Book(models.Model):
title = models.CharField(max_length=250)
author = models.CharField(max_length=250)
class WordInBook(models.Model):
book = models.ForeignKey("Book")
word = models.ForeignKey("Word")
相应的序列化器:
class BookSerializer(ModelSerializer):
wordinbook_set = WordInBookSerializer(many=True)
class Meta:
model = Book
fields = ('id', 'title', 'author', 'wordinbook_set')
class WordInBookSerializer(ModelSerializer):
class Meta:
model = WordInBook
fields = ('word')
现在我想分页wordinbook_set。在序列化器之外很容易:
book = Book.objects.get(pk=book_id)
paginator = Paginator(book.wordinbook_set.all(), 10)
words = paginator.page(page).object_list
但这给我留下了两个独立的序列化对象。
问题:如何在序列化程序中对wordinbook_set进行分页?
生成的json应如下所示:
{id: '...', title: '...', author: '...', wordinbook_set: [ 10 WordInBook objects here ]}
答案 0 :(得分:4)
由于在DRF 3.1中删除了PaginationSerializer,您必须实现自己的逻辑,有关详细信息,请参阅: https://stackoverflow.com/a/31500287/7469841
因此,您必须更改BookSerializer以包括以下分页行为:
BookSerializer
class BookSerializer(ModelSerializer):
wordinbook_set = serializers.SerializerMethodField('paginated_wordinbook')
class Meta:
model = Book
fields = ('id', 'title', 'author', 'wordinbook_set')
def paginated_wordinbook(self, obj):
page_size = self.context['request'].query_params.get('size') or 10
paginator = Paginator(obj.wordinbook_set.all(), page_size)
page = self.context['request'].query_params.get('page') or 1
words_in_book = paginator.page(page)
serializer = WordInBookSerializer(words_in_book, many=True)
return serializer.data
首先,您必须使用 django.core.paginator 中的 Paginator 来对可迭代对象进行分页:
paginator = Paginator(obj.wordinbook_set.all(), page_size)
然后从分页数据中获取目标页面:
words_in_book = paginator.page(page)
使用 many = True :
序列化分页集serializer = WordInBookSerializer(words_in_book, many=True)
另外,为了使页面大小动态,您可以使用 query_params 来接收所需的页面大小,例如,您可以选择请求中的页面大小为10,而在不同的请求中为100;检索页面大小:
page_size = self.context['request'].query_params.get('size') or 10
最后,为了让用户请求某个页面,再次使用 query_params 来接收它:
page = self.context['request'].query_params.get('page') or 1
答案 1 :(得分:1)
首先 - 在@detail_route
上定义BooksViewSet
- 让我们说出书中字样:
@detail_route(method=['GET'], url_path='word-in-book')
def word_in_book(self, request, *args, **kwargs):
object = self.get_object()
queryset = object.wordinbook_set.all()
page = self.paginate_queryset(queryset)
if page is not None:
serializer = WordInBookSerializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
通过这种方式,您将获得额外的端点:
/books/1/word-in-book/
会返回书籍模型中单词的分页结果。
希望这有帮助。
我相信你的情况下的分页是不可能的 - 你可以稍微改变一下代码然后回答:10个第一个对象。