由于基于某些条件使用了不同的序列化器,我更喜欢使用APIView和覆盖get函数。我对APIView感到满意,但现在我需要分页功能,我很难实现它。这就是为什么我想切换到GenericAPIView,但由于使用了多个序列化器,我不知道我该怎么做。
class ItemsAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get(self, request, format=None):
"""
Return a list of all devices of this user.
"""
reply = {}
try:
products = BaseItem.objects.owned_items().filter(owner=request.user)
reply['data'] = OwnedItemSerializer(products, many=True).data
items = BaseItem.objects.dev_items().filter(owner=request.user)
reply['data'].extend(ItemSerializer(items, many=True).data)
except:
reply['data'] = []
return Response(reply, status.HTTP_200_OK)
更新
我尝试的另一种方式是
class ItemsAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get(self, request, format=None):
"""
Return a list of all items with product of this user.
"""
reply = {}
print ('request', request.META.get('REMOTE_ADDR'))
try:
products = BaseItem.objects.owned_items().filter(owner=request.user)
reply['data'] = OwnedItemSerializer(products, many=True).data
items = BaseItem.objects.dev_items().filter(owner=request.user)
page = self.paginate_queryset(items)
print ('page', page) # i always get None even when pass url as api/items?page=1
if page is not None:
reply['data'].extend(ItemSerializer(page, many=True).data)
reply['data'].extend(ItemSerializer(items, many=True).data)
except:
reply['data'] = []
return Response(reply, status.HTTP_200_OK)
@property
def paginator(self):
"""
The paginator instance associated with the view, or `None`.
"""
if not hasattr(self, '_paginator'):
print (hasattr(self, '_paginator'))
if self.pagination_class is None:
self._paginator = None
else:
self._paginator = self.pagination_class()
return self._paginator
def paginate_queryset(self, queryset):
"""
Return a single page of results, or `None` if pagination is disabled.
"""
print ('queryset', queryset)
if self.paginator is None:
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
def get_paginated_response(self, data):
"""
Return a paginated style `Response` object for the given output data.
"""
assert self.paginator is not None
return self.paginator.get_paginated_response(data)
没有任何办法可行。我哪里做错了?
答案 0 :(得分:0)
你真的需要两个序列化器吗?
我认为使用单个Serializer 和自定义to_representation
可能是更好的选择:
class ItemSerializer(ModelSerializer):
# Your fields
def to_representation(self, instance):
data = super(ItemSerializer, self).to_representation(instance)
request = self.context.get('request')
if request and instance.is_owned_by(request.user):
return self.owner_to_representation(data, instance) # TO IMPLEMENT
return data
然后,您可以使用通用视图。您的代码更简洁,更简单,您不必担心分页:
class ItemList(generics.ListAPIView):
serializer_class = ItemSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
return BaseItem.objects.owned_items()| BaseItem.objects.dev_items()
答案 1 :(得分:0)
这就像导入您的paginator一样简单,并在APIView中手动调用它。
class PollView(views.APIView):
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication,)
paginator = CustomPagination()
def get(self, request):
queryset = Poll.objects.all()
context = self.paginator.paginate_queryset(queryset, request)
serializer = PollSerializer(context, many=True)
return self.paginator.get_paginated_response(serializer.data)
注意:自定义类不是必需的,您只需从脚本顶部的rest_framework.pagination导入即可。我创建了一个继承自PageNumberPagination的CustomPagination类,以便根据文档设置page_size查询 - http://www.django-rest-framework.org/api-guide/pagination/