Django REST Framework 中的分页关系? [英] Paginate relationship in Django REST Framework?

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

问题描述

我们的 API 使用 Django REST 框架,我们需要对返回多个项目的关系字段进行分页.

We are using Django REST Framework for our API and we have a need to paginate relationship fields that return multiple items.

使用类似于文档中的示例进行演示:

To demonstrate using examples similar to those in the documentation:

class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = ('order', 'title')

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')

相册的序列化输出示例:

Example serialized output for an Album:

{
    'album_name': 'The Grey Album',
    'artist': 'Danger Mouse'
    'tracks': [
        {'order': 1, 'title': 'Public Service Annoucement'},
        {'order': 2, 'title': 'What More Can I Say'},
        {'order': 3, 'title': 'Encore'},
        ...
    ],
}

如果专辑中有数百首曲目,这就会成为问题.在这种情况下,有没有办法对曲目"进行分页?

This becomes problematic where there are say hundreds of tracks in the Album. Is there a way to paginate the 'tracks' in this case?

理想情况下,我知道在这种情况下,曲目"可能指向一个 API URL,该 URL 只返回特定专辑的曲目 - 反过来可以轻松地进行分页.这种方法的缺点是获得前几首曲目所需的额外请求(以及因此延迟等).在我们的例子中,重要的是我们能够通过对 Album API 的单个请求获得至少一些曲目,然后在需要时动态加载其余曲目.

Ideally, I know that in cases like this, the 'tracks' should maybe point to an API URL that just returns the Tracks for a particular Album - which in turn can be paginated easily. The down side to that approach being the extra request (and hence delay, etc) required to get even the first few tracks. In our case, its important that we be able to get at least a few of the Tracks with the single request to the Album API and then dynamically load the rest of the tracks as and when required.

DRF 是否为此提供任何特定功能或模式?或者有什么解决办法?

Does the DRF offer any specific feature or pattern for this? Or are there any work arounds?

推荐答案

自 DRF 3.1 起,不支持 PaginationSerializer.这是解决方案.

Since DRF 3.1, PaginationSerializer is not supported. Here's solution.

settings.py

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 5
}

<小时>

serializers.py

from myapp.models import Album, Track
from rest_framework import pagination, serializers

class AlbumSerializer(serializers.HyperlinkedModelSerializer):
    tracks = serializers.SerializerMethodField('paginated_tracks')

    class Meta:
        model = Album

    def paginated_tracks(self, obj):
        tracks = Track.objects.filter(album=obj)
        paginator = pagination.PageNumberPagination()
        page = paginator.paginate_queryset(tracks, self.context['request'])
        serializer = TrackSerializer(page, many=True, context={'request': self.context['request']})
        return serializer.data

class TrackSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Track

或者你可以用 def paginated_tracks 代替

from rest_framework.settings import api_settings

    def get_paginated_tracks(self, obj):
        tracks = Track.objects.filter(album=obj)[:api_settings.PAGE_SIZE]
        serializer = TrackSerializer(tracks, many=True, context={'request': self.context['request']})
        return serializer.data

它甚至需要比上面更少的查询.

It even requires one less queries than above.

这篇关于Django REST Framework 中的分页关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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