django restframework中的嵌套对象分页

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

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, 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
,在相关对象分页响应链接中有什么区别吗?嗯,我不这么认为。试试下面我的方法,让我知道你进展如何。。。