Django-Rest-Framework:分页嵌套的对象 [英] Django-Rest-Framework: Paginate nested object

查看:88
本文介绍了Django-Rest-Framework:分页嵌套的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个模型:

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 ]}

推荐答案

由于在DRF 3.1中删除了PaginationSerializer,因此您必须实现自己的逻辑,有关更多详细信息,请参见: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆