在django restframework中

时间:2018-05-16 14:51:50

标签: django

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
      }
   ]
}

任何人都可以指导我如何对嵌套数据进行分页。

2 个答案:

答案 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_linkget_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