PS:Django 2.0.4和django-restframework 3.7.7
我有一个Place模型来存储一个地方的细节,还有一个模型PlacePhoto来存储那个地方的照片
地方模型是这样的:
class Place(models.Model):
name = models.CharField(_('name'), max_length=1024, blank=True, null=True)
description = models.TextField(blank=True, null=True)
和PlacePhoto模型是这样的:
class PlacePhoto(models.Model):
place = models.ForeignKey(Place, on_delete=models.CASCADE,
related_name='photos')
image = models.ImageField()
My Place序列化程序是这样的:
class PlaceSerializer(serializers.ModelSerializer):
photos = serializers.SerializerMethodField()
class Meta:
model = Place
fields = ('id', 'name', 'photos', )
def get_photos(self, obj):
photos = obj.photos.all()
request = self.context.get('request')
serializer = PlacePhotoSerializer(photos, many=True, context={'request': request})
paginator = RelationPaginator()
paginated_data = paginator.paginate_queryset(serializer.data, request)
return paginator.get_paginated_response(paginated_data)
class RelationPaginator(pagination.PageNumberPagination):
def get_paginated_response(self, data):
return {
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'count': self.page.paginator.count,
'results': data
}
class PlacePhotoSerializer(serializers.ModelSerializer):
class Meta:
model = PlacePhoto
fields = ('image', )
我正在尝试对一个地方的照片进行分页,但不幸的是我没有成功。 传递给paginator的请求对象与place api的请求对象相同,所以照片absolute_uri与place api的照片相同。
{
"count":6,
"next":"http://localhost:8000/api/v1/places/?page=2",
"previous":null,
"results":[
{
"id":1832,
"name":"The National",
"locality":"New York",
"location":{
"latitude":-73.97212481,
"longitude":40.756645889989
},
"visited_count":0,
"interested_count":0,
"photos":{
"next":"http://localhost:8000/api/v1/places/?page=2",
"previous":null,
"count":10,
"results":[
{
"image":"https://s3-ap-southeast-1.amazonaws.com/media.testpress.in/buena-dev/places/The%20National/images/cf80a3136a614dd889fc5920829ef289"
}
]
},
"price_level":2,
"types":[
"bar",
"restaurant",
"food",
"point_of_interest",
"establishment"
],
"distance":null
}
]
}
任何人都可以指导我如何对嵌套数据进行分页。
答案 0 :(得分:2)
尝试我上面的评论建议,如果没有,也许您需要这样的东西:
class RelationPaginator(pagination.PageNumberPagination):
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
}
'count': self.page.paginator.count,
'results': data
})
如果您需要在settings.py
中使用它,则无需在views.py
中将其设置为默认值:
class SomeView(generics.ListAPIView):
queryset = PlacePhoto.objects.all()
serializer_class = PlacePhotoSerializer
pagination_class = RelationPagination
N.B。免责声明 :这是您的自定义分页RelationPaginator
类的最佳猜测,如果这不起作用,则可能需要整个代码库来理解为什么分页不起作用。
答案 1 :(得分:2)
我认为您应该在分页器中覆盖get_next_link
和get_previous_link
而不是get_paginated_response
:
from rest_framework.reverse import reverse
from rest_framework.utils.urls import replace_query_param, remove_query_param
class RelationPaginator(pagination.PageNumberPagination):
def get_next_link(self):
if not self.page.has_next():
return None
url = reverse('your_url_name', request=self.request) ## just pass the url name of the main endpoint that handles the photos list
page_number = self.page.next_page_number()
return replace_query_param(url, self.page_query_param, page_number)
def get_previous_link(self):
if not self.page.has_previous():
return None
url = reverse('your_url_name', request=self.request) ## just pass the url name of the main endpoint that handles the photos list
page_number = self.page.previous_page_number()
if page_number == 1:
return remove_query_param(url, self.page_query_param)
return replace_query_param(url, self.page_query_param, page_number)
参考:
1- reverse