Django REST框架中的分页关系?

Django REST框架中的分页关系?,django,api,pagination,django-rest-framework,django-pagination,Django,Api,Pagination,Django Rest Framework,Django Pagination,我们的API使用Django REST框架,需要对返回多个项的关系字段进行分页 要使用与中类似的示例进行演示,请执行以下操作: 相册的序列化输出示例: { 'album_name': 'The Grey Album', 'artist': 'Danger Mouse' 'tracks': [ {'order': 1, 'title': 'Public Service Annoucement'}, {'order': 2, 'title':

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

要使用与中类似的示例进行演示,请执行以下操作:

相册的序列化输出示例:

{
    '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'},
        ...
    ],
}
如果专辑中有数百首曲目,这就成了问题。在这种情况下,有没有办法对“轨迹”进行分页

理想情况下,我知道在这种情况下,“曲目”可能会指向一个API URL,该URL只返回特定专辑的曲目,而这反过来又可以很容易地分页。这种方法的缺点是需要额外的请求(因此需要延迟等),以获得前几条轨道。在我们的例子中,重要的是我们能够通过对Album API的单个请求获得至少一些曲目,然后在需要时动态加载其余的曲目


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

如果将来出现比特腐烂,请从上面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

由于DRF 3.1,
分页序列化程序
不受支持。这是解决办法


设置.py


序列化程序.py

或者,您可以用
def paginated_曲目
代替

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

它甚至需要比上面少一个查询。

Malcolm Box和Deepak Prakash do的方法可以帮助序列化Relathip对象,但正如@eugene之前所说,它只适用于单个明矾。对于专辑,我们可以这样做:

序列化程序.py

api.py

然后你可能会得到回应:

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

      },
      {'album_name': 'The John Album',
          'tracks': [
                   {'order': 1, 'title': 'Public Annoucement'},
                   {'order': 2, 'title': 'What sd Can I Say'},
                   {'order': 3, 'title': 'sd'},
                      ...
},
 ......
}

注:供将来参考。这是Django REST framework邮件列表中的后续内容。您可以在这里参考我对相同问题的回答,但如何在分页的_轨道中获取页面大小参数和页面参数?好的,我知道了
request=self.context['request']
FYI-
Paginator
来自django.core.Paginator import Paginator。这对于单个唱片集很好,但如果您正在检索唱片集列表(也需要分页),请求对象中设置的分页参数可能不应用于轨道分页。@eugene
paginator.page\u query\u param='track\u page'
paginator.page\u size\u query\u param='track\u page\u size'
可以解决这个问题。另外,如果
返回paginator.get_paginated_response(serializer.data).data
输出与顶层的分页是一致的。当我尝试第一种解决方案时,我发现
页面
paginate_queryset
的返回值仍然是一个简单的对象列表。根据,我认为获取分页数据的正确方法是在调用
paginate\u queryset
之后调用
get\u paginated\u response
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
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
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')
        depth=1
class getAPIView(generics.ListAPIView):
    serializer_class=TrackSerializer
    filter_backends = (filters.OrderingFilter,)
    def get_queryset(self):
        queryset=Track.objects.all()
        return queryset
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        serializer = self.get_serializer(page, many=True)
        data=serializer.data
        albums=Album.objects.values_list('album_name').all()
        trackObjs=[]
        albumObjs=[]
        self.categoryKeyList(albums,albumObjs)
        if page is not None:
            for p in page:
                for n,i in enumerate(albums):
                     if re.search(str(p.alum),str(i)):
                        albumObjs[n]['track'].append(p)
        data={}
        data['count']=self.get_paginated_response(self).data['count']
        data['next']=self.get_paginated_response(self).data['next']
        data['previous']=self.get_paginated_response(self).data['previous']
        data['pageNumber'] = self.paginator.page.number
        data['countPage'] = self.paginator.page.paginator._count
        serializer=ClientsCategorySerializer(categoryObjs,many=True)
        data['result']=serializer.data
        return Response({'data':data,'success':'1','detail':u'获得客户列表成功'})
    def categoryKeyList(self,albums,albumObjs):
        for i in albums:
            albumObjs={}
            albumObjs['album_name']=i[0]
            track=[]
            albumObj['track']=track
            albumObjs.append(albumObj)
{
    data[
     {
          'album_name': 'The Grey Album',
          'tracks': [
                   {'order': 1, 'title': 'Public Service Annoucement'},
                   {'order': 2, 'title': 'What More Can I Say'},
                   {'order': 3, 'title': 'Encore'},
                      ...

      },
      {'album_name': 'The John Album',
          'tracks': [
                   {'order': 1, 'title': 'Public Annoucement'},
                   {'order': 2, 'title': 'What sd Can I Say'},
                   {'order': 3, 'title': 'sd'},
                      ...
},
 ......
}