django restframework中的嵌套对象分页
PS:Django 2.0.4和Django restframework 3.7.7 我有一个地方模型来存储一个地方的细节,还有一个模型PlacePhoto来存储那个地方的照片 地点模型是这样的:django restframework中的嵌套对象分页,django,Django,PS:Django 2.0.4和Django restframework 3.7.7 我有一个地方模型来存储一个地方的细节,还有一个模型PlacePhoto来存储那个地方的照片 地点模型是这样的: class Place(models.Model): name = models.CharField(_('name'), max_length=1024, blank=True, null=True) description = models.TextField(blank=True
class Place(models.Model):
name = models.CharField(_('name'), max_length=1024, blank=True, null=True)
description = models.TextField(blank=True, null=True)
class PlacePhoto(models.Model):
place = models.ForeignKey(Place, on_delete=models.CASCADE,
related_name='photos')
image = models.ImageField()
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', )
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
})
PlacePhoto模型是这样的:
class Place(models.Model):
name = models.CharField(_('name'), max_length=1024, blank=True, null=True)
description = models.TextField(blank=True, null=True)
class PlacePhoto(models.Model):
place = models.ForeignKey(Place, on_delete=models.CASCADE,
related_name='photos')
image = models.ImageField()
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', )
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
})
My Place序列化程序如下所示:
class Place(models.Model):
name = models.CharField(_('name'), max_length=1024, blank=True, null=True)
description = models.TextField(blank=True, null=True)
class PlacePhoto(models.Model):
place = models.ForeignKey(Place, on_delete=models.CASCADE,
related_name='photos')
image = models.ImageField()
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', )
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
})
我正在尝试为一个地方的照片分页,但不幸的是我没有成功。
传递给paginator的请求对象与place api的请求对象相同,因此照片绝对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
}
]
}
任何人都可以指导我如何对嵌套数据进行分页。试试我上面的评论建议,如果没有,也许你需要这样的建议:
class Place(models.Model):
name = models.CharField(_('name'), max_length=1024, blank=True, null=True)
description = models.TextField(blank=True, null=True)
class PlacePhoto(models.Model):
place = models.ForeignKey(Place, on_delete=models.CASCADE,
related_name='photos')
image = models.ImageField()
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', )
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.免责声明:这是来自您的自定义分页关系分页器
类的最佳猜测,如果这不起作用,可能需要您的整个代码库来理解您的分页不起作用的原因…尝试我上面的评论建议,如果不起作用,也许您需要这样的建议:
class Place(models.Model):
name = models.CharField(_('name'), max_length=1024, blank=True, null=True)
description = models.TextField(blank=True, null=True)
class PlacePhoto(models.Model):
place = models.ForeignKey(Place, on_delete=models.CASCADE,
related_name='photos')
image = models.ImageField()
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', )
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
类中的最佳猜测,如果这不起作用,可能需要整个代码库来理解分页不起作用的原因…我认为您应该在分页器中覆盖get_next_链接和get_previous_链接
,而不是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-我认为您应该覆盖分页器中的get\u next\u link
和get\u previous\u link
而不是get\u paginated\u 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-Hi Umair-您是否已将REST_FRAMEWORK={'DEFAULT_PAGINATION_CLASS':'REST_FRAMEWORK.PAGINATION.CursorPagination'、'PAGE_SIZE':100}
添加到您的settings.py
文件中?对于任何在这件事上受到打击的人,(悲哀地)我用我的相关模型api路径覆盖raquest.path,然后将其传递给序列化程序,然后再次还原相同的内容,从而提出了一个黑客解决方案。@MichealJRoberts我使用的是PageNumberPagination
,在相关对象分页响应链接中有什么区别吗?嗯,我不这么认为。试试下面我的方法,让我知道你进展如何…嗨,Umair-你有没有在你的settings.py
文件中添加REST\u FRAMEWORK={'DEFAULT\u PAGINATION\u CLASS':'REST\u FRAMEWORK.PAGINATION.CursorPagination','PAGE\u SIZE':100}
给任何在这件事上受到打击的人,(悲哀地)我用我的相关模型api路径覆盖raquest.path,然后将其传递给序列化程序,然后再次还原相同的内容,从而提出了一个黑客解决方案。@MichealJRoberts我使用的是PageNumberPagination
,在相关对象分页响应链接中有什么区别吗?嗯,我不这么认为。试试下面我的方法,让我知道你进展如何。。。