18

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')

アルバムのシリアル化された出力の例:

{
    '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 を指す必要があることを知っています。これにより、簡単にページ分割できます。そのアプローチのマイナス面は、最初の数トラックを取得するために必要な追加のリクエスト (したがって遅延など) です。私たちの場合、Album API への 1 回のリクエストで少なくともいくつかのトラックを取得し、必要に応じて残りのトラックを動的にロードできることが重要です。

DRF は、これに対して特定の機能やパターンを提供していますか? または、回避策はありますか?

4

3 に答える 3

1

Malcolm Box と Deepak Prakash の方法は、関係オブジェクトをシリアライズするのに役立ちますが、@eugene が前に言ったように、単一のミョウバンに対してのみ機能します。アルバムの場合、次のことができます。

serializers.py

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

apis.py

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'},
                      ...
},
 ......
}
于 2017-01-11T12:54:48.260 に答える