Django-Rest-Framework:对嵌套对象进行分页 [英] Django-Rest-Framework: Paginate nested object
问题描述
我有两个模型:
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 进行分页.在序列化器之外很容易:
Now I want to paginate the wordinbook_set. Outside of serialiser it is easy:
book = Book.objects.get(pk=book_id)
paginator = Paginator(book.wordinbook_set.all(), 10)
words = paginator.page(page).object_list
但这给我留下了两个单独的序列化对象.
But that leaves me with two separate serialized objects.
问题:如何在序列化程序中对 wordinbook_set 进行分页?
生成的 json 应如下所示:
Question: how do I paginate wordinbook_set inside the serializer?
The resulting json should look like this:
{id: '...', title: '...', author: '...', wordinbook_set: [ 10 WordInBook objects here ]}
推荐答案
由于 PaginationSerializer 在 DRF 3.1 中被移除,你必须实现你自己的逻辑,更多细节参考:https://stackoverflow.com/a/31500287/7469841
Since PaginationSerializer was removed in DRF 3.1, you have to implement your own logic, for further details refer to : https://stackoverflow.com/a/31500287/7469841
因此,您必须更改 BookSerializer 以包含如下分页行为:
So you have to change your BookSerializer to include the pagination behaviour as following :
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 对可迭代对象进行分页:
Firstly You have to use the Paginator found in django.core.paginator to paginate an iterable object:
paginator = Paginator(obj.wordinbook_set.all(), page_size)
然后从分页数据中获取目标页面:
Then get the target page from paginated data :
words_in_book = paginator.page(page)
使用many=True序列化分页集:
serializer = WordInBookSerializer(words_in_book, many=True)
还要使页面大小动态化,您可以使用 query_params 来接收所需的页面大小,例如您可以在请求中选择页面大小为 10,在不同请求中选择为 100,检索页面大小:
Also to make the page size dynamic you can use query_params to receive the desired page size, for example you can choose the page size to be 10 in a request and be 100 in a different request, to retrieve the page size:
page_size = self.context['request'].query_params.get('size') or 10
最后允许用户请求某个页面,再次使用query_params来接收它:
And finally to allow the user to request a certain page, use again the query_params to receive it:
page = self.context['request'].query_params.get('page') or 1
这篇关于Django-Rest-Framework:对嵌套对象进行分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!