Django REST框架中的Paginate关系?

Dee*_*ash 15 api django pagination django-pagination django-rest-framework

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

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

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')
Run Code Online (Sandbox Code Playgroud)

相册的序列化输出示例:

{
    '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'},
        ...
    ],
}
Run Code Online (Sandbox Code Playgroud)

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

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

DRF是否为此提供任何特定功能或模式?或者有任何工作吗?

Mal*_*Box 9

如果未来有点腐烂,请从上面的Tom链接复制回答:

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

class PaginatedTrackSerializer(pagination.PaginationSerializer):
    class Meta:
        object_serializer_class = TrackSerializer

class AlbumSerializer(serializers.ModelSerializer):

    tracks = serializers.SerializerMethodField('paginated_tracks')


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


    def paginated_tracks(self, obj):
        paginator = Paginator(obj.tracks.all(), 10)
        tracks = paginator.page(1)

        serializer = PaginatedTrackSerializer(tracks)
        return serializer.data
Run Code Online (Sandbox Code Playgroud)

  • 好,我知道了。`request = self.context['request']` (2认同)

Che*_*mer 9

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


settings.py

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 5
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

或者您也可以替换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
Run Code Online (Sandbox Code Playgroud)

它甚至比上面的查询少一个.