csv Django REST框架:如何在ModelViewSet中关闭/打开分页

31moq8wy  于 2023-11-14  发布在  Go
关注(0)|答案(8)|浏览(135)

我正在使用Django REST frameworkdjangorestframework-csv,并使用默认分页设置,但当请求的格式为“CSV”时,则不需要分页。可以使用以下命令禁用分页:
第一个月
是否可以动态地更改它?

class ObjectViewSet(BaseViewSet, viewsets.ModelViewSet):

    queryset = Object.objects.none()
    serializer_class = ObjectSerializer
    pagination_class = None # if format is "CSV"
    # pagination_class = None # if fromat isn't "CSV"

字符串
谢谢.

4szc88ey

4szc88ey1#

一个选项是通过设置no_page查询参数来动态禁用视图上的分页:

def paginate_queryset(self, queryset, request, view=None):
    if 'no_page' in request.query_params:
        return None

    return super().paginate_queryset(queryset, request, view)

字符串

dfty9e19

dfty9e192#

这个方案对我很有效

DRF版本:3.11.0
Django版本:2.2.7

默认情况下,分页是工作的,但当我将通过查询参数'no_page',然后分页将被禁用:像:http://localhost:8000/api/city/?no_page

class CityListView(generics.ListCreateAPIView):
    serializer_class = serializers.CitySerializer
    def paginate_queryset(self, queryset, view=None):
        if 'no_page' in self.request.query_params:
            return None
        else:
            return self.paginator.paginate_queryset(queryset, self.request, view=self)

字符串

0ve6wy6x

0ve6wy6x3#

如果您只想按客户端动态打开或关闭分页,则可以将Pagination类自定义为:

class Pagination(PageNumberPagination):
    page_size_query_param = 'page_size'
    max_page_size = 100

    def get_page_size(self, request):
        if self.page_size_query_param:
            page_size = min(int(request.query_params.get(self.page_size_query_param, self.page_size)),
                        self.max_page_size)
            if page_size > 0:
                return page_size
            elif page_size == 0:
                return None
            else:
                pass
        return self.page_size

字符串
使用这个类作为你的pagination_class,你可以通过请求URL“http://www.example.com/some_object/?page_size=0“关闭分页,?page_size=0将禁用分页。如果你只是想在请求格式为CVS时禁用分页,你可以试试danilke说的。

bksxznpy

bksxznpy4#

简单地说,你可以在你的类中使用pagination_class = None

class MyClassBasedView(ModelViewSet):
    pagination_class = None

字符串

qncylg1j

qncylg1j5#

它不再起作用了(至少在最新版本中不起作用),你应该这样做

def paginate_queryset(self, queryset, request, view=None):
     if 'page' not in request.query_params:
            return queryset
     return super().paginate_queryset(queryset)

字符串
并在列表方法中使用self.paginate_queryset(queryset, request)调用函数

fzsnzjdm

fzsnzjdm6#

解决方案是:

class PaginatedCSVRenderer (CSVRenderer):
    results_field = 'results'

    def render(self, data, *args, **kwargs):
        if not isinstance(data, list):
            data = data.get(self.results_field, [])
        return super(PaginatedCSVRenderer, self).render(data, *args, **kwargs)

字符串
然后:

class ObjectViewSet(BaseViewSet, viewsets.ModelViewSet):

    queryset = Object.objects.none()
    serializer_class = ObjectSerializer
    renderer_classes =  (JSONRenderer, PaginatedCSVRenderer)


并从设置中删除:

'PAGE_SIZE': 10,

ncecgwcz

ncecgwcz7#

也许有一种更适合未来的方法-打开my_venv/lib/python3.8/site-packages/rest_framework/generics.py-替换my_venv和你的Python版本,滚动到第165行并复制paginate_queryset的方法签名。还要检查它返回什么if self.paginator is None-如果你想禁用分页,那就是返回什么。
在DRF 3.11中,父方法签名是paginate_queryset(self, queryset),而if self.paginator is None返回None,所以我使用:

def paginate_queryset(self, queryset):
    if 'page_id' in self.request.query_params:
        return None
    return super().paginate_queryset(queryset)

字符串
我还没有测试过它,但我猜OP问题的答案是(假设一个相当默认的DRF配置):

if ('format' in self.request.query_params and 
        self.request.query_params['format'] == 'csv'):

hmmo2u0o

hmmo2u0o8#

我的解决方案:

  • 默认但可自定义的page_size
  • 仅在提供page参数时应用分页
  • 否则返回整个列表
# paginators.py

class CustomPagination(PageNumberPagination):
    page_size = 10  # default
    page_size_query_param = "page_size"  # param to set a custom page_size
    max_page_size = 50

    def paginate_queryset(self, queryset, request, view=None):
        # if the page param is not provided, do not apply pagination
        if request.query_params.get(self.page_query_param, None) is None:
            return None

        return super().paginate_queryset(queryset, request, view)

字符串
使用方法:

#views.py

from .paginators import CustomPagination

class ObjectViewSet(BaseViewSet, viewsets.ModelViewSet):
    queryset = Object.objects.none()
    serializer_class = ObjectSerializer
    pagination_class = CustomPagination


测试并使用Django 4.2和DRF 3.14。

相关问题