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

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

问题描述

我们正在为我们的API使用Django REST框架,我们需要分页返回多个项目的关系字段。



为了演示使用与文档

 code> 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 Gray Album',
'artist':'Danger Mouse'
'轨道':[
{'order':1,'title':'Public Service Annoucement'},
{'order':2,'title':'我还能说什么'},
{'order':3,'title':'Encore'},
...
],
}

这是一个问题,那里有几百条曲目在专辑中。在这种情况下,是否有一种分页轨道的方法?



理想情况下,我知道在这种情况下,'track'应该指向一个API URL那只是返回一个特定的专辑的曲目,而这又可以很容易地分页。这种方法的缺点是获得甚至前几个轨迹所需的额外请求(因此也是延迟等)。在我们的例子中,重要的是我们可以通过对Album API的单一请求获得至少一些轨道,然后根据需要动态加载剩余的轨道。



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

解决方案

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






settings.py

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






serializers.py

从myapp.models导入相册,从rest_framework导入分页跟踪
,序列化

class AlbumSerializer(serializers $ h
track = 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 ['reques t']}
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

它甚至比以上要求少一个。


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?

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.

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

解决方案

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

OR you can substitute def paginated_tracks for

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框架中的分页关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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