Python中Django Rest Framework如何在ModelViewSet中同时实现分页和获取所有数据
RT,求大神指教,🙏
Python中Django Rest Framework如何在ModelViewSet中同时实现分页和获取所有数据
在DRF的ModelViewSet里,要同时支持分页和获取所有数据,最直接的办法是自定义一个视图集,根据请求参数动态切换分页行为。下面是一个完整的实现示例:
from rest_framework import viewsets, pagination
from rest_framework.response import Response
from rest_framework.decorators import action
from django.core.paginator import Paginator, EmptyPage
from .models import YourModel
from .serializers import YourModelSerializer
class YourModelViewSet(viewsets.ModelViewSet):
queryset = YourModel.objects.all()
serializer_class = YourModelSerializer
pagination_class = pagination.PageNumberPagination
def list(self, request, *args, **kwargs):
# 检查请求参数中是否有'all'参数
get_all = request.query_params.get('all', '').lower() == 'true'
if get_all:
# 禁用分页,返回所有数据
self.paginator = None
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
else:
# 使用默认的分页逻辑
return super().list(request, *args, **kwargs)
这样配置后,你可以通过不同的URL参数来控制分页:
- 正常分页:
/api/yourmodel/ - 获取所有数据:
/api/yourmodel/?all=true
如果你想要更灵活的控制,还可以添加一个自定义的action:
class YourModelViewSet(viewsets.ModelViewSet):
# ... 其他代码同上 ...
@action(detail=False, methods=['get'])
def all(self, request):
"""获取所有数据的专用端点"""
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
这样就有了两个端点:
/api/yourmodel/- 分页数据/api/yourmodel/all/- 所有数据
两种方式都能很好地解决你的需求,第一种更简洁,第二种更符合RESTful风格。根据你的具体场景选择即可。
总结:通过动态控制分页器或添加专用action来实现分页和全数据的切换。
你可以这样实现
from django.shortcuts import render
from django.contrib.auth.models import User
import random
from rest_framework.response import Response
# Create your views here.
b = [str(i) for i in range(10)]
for i in range(10):
a = random.sample(b, 5)
User.objects.update_or_create(username=’’.join(a))
from rest_framework import serializers
from rest_framework import pagination
from rest_framework.viewsets import ModelViewSet
from collections import OrderedDict, namedtuple
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = 'all’
class UserPagination(pagination.PageNumberPagination):
page_size = 20
def get_paginated_response(self, data):
return Response(OrderedDict([
(‘count’, self.page.paginator.count),
(‘next’, self.get_next_link()),
(‘previous’, self.get_previous_link()),
(‘page_size’, self.page_size),
(‘results’, data)
]))
class UserViewset(ModelViewSet):
serializer_class = UserSerializer
pagination_class = UserPagination
def get_queryset(self):
return User.objects.all()
def list(self, request, *args, **kwargs):
status = request.query_params.get(“status”)
users = self.get_queryset()
if status == ‘1’:
self.paginator.page_size = users.count()
page = self.paginate_queryset(users)
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
效果如下

感谢

