将上下文传递给 Django Rest Framework 中的分页类

问题描述 投票:0回答:3

我有自定义分页类。

class BasicPagination(PageNumberPagination):
 page_size = 3
 page_size_query_param = 'page_size'
 max_page_size = 20

 def get_paginated_response(self, data):
    has_next, has_previous = False, False
    if self.get_next_link():
        has_next = True
    if self.get_previous_link():
        has_previous = True

    meta = collections.OrderedDict([
        ('page', self.page.number),
        ('has_next', has_next),
        ('has_previous', has_previous),
    ])
    ret = collections.OrderedDict(meta=meta)
    ret["results"] = data
    return Response(ret)

我还有一个

generics.ListCreateAPIView
类,它具有自定义查询集方法和
pagination_class = BasicPagination
。我想将
self.kwargs.get("obj_type")
传递给分页类,以便它显示
obj_type
而不是
results
。这是我的班级观点。 如何将
self.kwargs
传递到分页类?

class Translation(ListCreateAPIView):

 pagination_class = BasicPagination
 serializer_class = TranslationStepSerializer

 def get_queryset(self):
    api_controller = ApiController.load()
    obj_type = self.kwargs.get("obj_type")
    pk = self.kwargs.get("pk")

    data = api_controller.get_translation(obj_type, pk)

    return data if not None else None
python django parameters pagination django-rest-framework
3个回答
0
投票

我假设-

它显示 obj_type 而不是结果

您的意思是您希望回复中的关键是

obj_type
而不是“结果”。也就是说 obj_type 是代码中的一个字符串。

我有类似的要求,我想根据某些条件修改响应。作为解决方法,我将所有必需的参数添加到

data
本身,通过它我自定义了分页响应。

def get_paginated_response(self, data):

    if self.get_next_link():
        next_page = data["page_no"] + 1
    else:
        next_page = 0

    response = {
        "next": next_page,
        'count': self.page.paginator.count,
        'cards': data["cards"],
        'companies': data["companies"],
        'positions': data["positions"],
        'cities':data["cities"]
    }

    tags =  data.get('tags', None)

    if tags is not None:
        response['tags'] = tags

    return Response(data=response)

根据您的情况,您可以执行以下操作:

ret[data['obj_type']] = data['results']

在此之前,在查询集中:

data = {'results': api_controller.get_translation(obj_type, pk), 'obj_type': obj_type}

0
投票

我知道已经晚了。但在您的视图集中,您可以覆盖

get_paginated_response
list
方法:

class Translation(ListCreateAPIView):

 pagination_class = BasicPagination
 serializer_class = TranslationStepSerializer

 def get_queryset(self):
    api_controller = ApiController.load()
    obj_type = self.kwargs.get("obj_type")
    pk = self.kwargs.get("pk")

    
    data = api_controller.get_translation(obj_type, pk)

    return data if not None else None
 
 def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())

    page = self.paginate_queryset(queryset)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data, extra_keys={'obj_type': self.kwargs.get("obj_type")})

    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)

 def get_paginated_response(self, data, extra_keys):
    """
    Return a paginated style `Response` object for the given output data.
    """
    assert self.paginator is not None
    return self.paginator.get_paginated_response(data, extra_keys)

在你的分页类中,你可以得到

extra_keys
作为参数:

 class BasicPagination(PageNumberPagination):
     page_size = 3
     page_size_query_param = 'page_size'
     max_page_size = 20

     def get_paginated_response(self, data, extra_keys):

        # here you can get your passed keys 
        # for example for obj_type
        obj_type = extra_keys['obj_type']
        
        has_next, has_previous = False, False
        if self.get_next_link():
            has_next = True
        if self.get_previous_link():
            has_previous = True

        meta = collections.OrderedDict([
            ('page', self.page.number),
            ('has_next', has_next),
            ('has_previous', has_previous),
        ])
        ret = collections.OrderedDict(meta=meta)
        ret["results"] = data
        return Response(ret)

注意:我使用字典来传递变量,因为如果有其他变量要传递,这会更整洁。但你可以简单地传递你想要的变量。


0
投票

这是向分页类传递额外数据的简单方法

分页.py

class ResultsSetPagination(LimitOffsetPagination):
    page_size = 50
    max_limit = 150
    offset_query_param = 'page'
    limit_query_param = 'limit'
    def get_paginated_response(self, data, **kwargs):
        
        # return Response({
        #     # 'data': data
        # })
        return { 
            'links': {
                'next': self.get_next_link(),
                'previous': self.get_previous_link()
                },
            'data': data
        }

views.py


def list(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            # return self.get_paginated_response(serializer.data)
            return response.Response({
                'success': bool(queryset),
                **self.get_paginated_response(serializer.data),
                'extra': 'read.sanjaysikdar.dev'
            })

欢迎询问。

© www.soinside.com 2019 - 2024. All rights reserved.