如何在Django中使用rest framework实现分页
今天就跟大家聊聊有关如何在Django中使用rest framework实现分页,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
第一种分页PageNumberPagination
(1)urls.py
urlpatterns=[ re_path('(?P<version>[v1|v2]+)/page1/',Pager1View.as_view(),)#分页1 ]
(2)api/utils/serializers/pager.py
#api/utils/serializsers/pager.py fromrest_frameworkimportserializers fromapiimportmodels classPagerSerialiser(serializers.ModelSerializer): classMeta: model=models.Role fields="__all__"
(3)views.py
fromapi.utils.serializsers.pagerimportPagerSerialiser fromrest_framework.responseimportResponse fromrest_framework.paginationimportPageNumberPagination classPager1View(APIView): defget(self,request,*args,**kwargs): #获取所有数据 roles=models.Role.objects.all() #创建分页对象 pg=PageNumberPagination() #获取分页的数据 page_roles=pg.paginate_queryset(queryset=roles,request=request,view=self) #对数据进行序列化 ser=PagerSerialiser(instance=page_roles,many=True) returnResponse(ser.data)
(4)settings配置
REST_FRAMEWORK={ #分页 "PAGE_SIZE":2#每页显示多少个 }
自定义分页类
#自定义分页类 classMyPageNumberPagination(PageNumberPagination): #每页显示多少个 page_size=3 #默认每页显示3个,可以通过传入pager1/?page=2&size=4,改变默认每页显示的个数 page_size_query_param="size" #最大页数不超过10 max_page_size=10 #获取页码数的 page_query_param="page" classPager1View(APIView): defget(self,request,*args,**kwargs): #获取所有数据 roles=models.Role.objects.all() #创建分页对象,这里是自定义的MyPageNumberPagination pg=MyPageNumberPagination() #获取分页的数据 page_roles=pg.paginate_queryset(queryset=roles,request=request,view=self) #对数据进行序列化 ser=PagerSerialiser(instance=page_roles,many=True) returnResponse(ser.data)
第二种分页 LimitOffsetPagination
自定义
#自定义分页类2 classMyLimitOffsetPagination(LimitOffsetPagination): #默认显示的个数 default_limit=2 #当前的位置 offset_query_param="offset" #通过limit改变默认显示的个数 limit_query_param="limit" #一页最多显示的个数 max_limit=10 classPager1View(APIView): defget(self,request,*args,**kwargs): #获取所有数据 roles=models.Role.objects.all() #创建分页对象 pg=MyLimitOffsetPagination() #获取分页的数据 page_roles=pg.paginate_queryset(queryset=roles,request=request,view=self) #对数据进行序列化 ser=PagerSerialiser(instance=page_roles,many=True) returnResponse(ser.data)
返回的时候可以用get_paginated_response方法
自带上一页下一页
第三种分页CursorPagination
加密分页方式,只能通过点“上一页”和下一页访问数据
#自定义分页类3(加密分页) classMyCursorPagination(CursorPagination): cursor_query_param="cursor" page_size=2#每页显示2个数据 ordering='id'#排序 page_size_query_param=None max_page_size=None classPager1View(APIView): defget(self,request,*args,**kwargs): #获取所有数据 roles=models.Role.objects.all() #创建分页对象 pg=MyCursorPagination() #获取分页的数据 page_roles=pg.paginate_queryset(queryset=roles,request=request,view=self) #对数据进行序列化 ser=PagerSerialiser(instance=page_roles,many=True) #returnResponse(ser.data) returnpg.get_paginated_response(ser.data)
代码
版本、解析器、序列化和分页
#MyProject2/urls.py fromdjango.contribimportadmin fromdjango.urlsimportpath,include urlpatterns=[ #path('admin/',admin.site.urls), path('api/',include('api.urls')), ]
#api/urls.py fromdjango.urlsimportpath,re_path from.viewsimportUserView,PaserView,RolesView,UserInfoView,GroupView,UserGroupView from.viewsimportPager1View urlpatterns=[ re_path('(?P<version>[v1|v2]+)/users/',UserView.as_view(),name='api_user'),#版本 path('paser/',PaserView.as_view(),),#解析 re_path('(?P<version>[v1|v2]+)/roles/',RolesView.as_view()),#序列化 re_path('(?P<version>[v1|v2]+)/info/',UserInfoView.as_view()),#序列化 re_path('(?P<version>[v1|v2]+)/group/(?P<pk>\d+)/',GroupView.as_view(),name='gp'),#序列化生成url re_path('(?P<version>[v1|v2]+)/usergroup/',UserGroupView.as_view(),),#序列化做验证 re_path('(?P<version>[v1|v2]+)/pager1/',Pager1View.as_view(),)#分页1 ]
#api/models.py fromdjango.dbimportmodels classUserInfo(models.Model): USER_TYPE=( (1,'普通用户'), (2,'VIP'), (3,'SVIP') ) user_type=models.IntegerField(choices=USER_TYPE) username=models.CharField(max_length=32,unique=True) password=models.CharField(max_length=64) group=models.ForeignKey('UserGroup',on_delete=models.CASCADE) roles=models.ManyToManyField('Role') classUserToken(models.Model): user=models.OneToOneField('UserInfo',on_delete=models.CASCADE) token=models.CharField(max_length=64) classUserGroup(models.Model): title=models.CharField(max_length=32) classRole(models.Model): title=models.CharField(max_length=32)
#api/views.py importjson fromdjango.shortcutsimportrender,HttpResponse fromrest_framework.viewsimportAPIView fromrest_framework.requestimportRequest fromrest_framework.versioningimportURLPathVersioning from.importmodels ##########################################版本和解析器##################################################### classUserView(APIView): defget(self,request,*args,**kwargs): #获取版本 print(request.version) #获取处理版本的对象 print(request.versioning_scheme) #获取浏览器访问的url,reverse反向解析 #需要两个参数:viewname就是url中的别名,request=request是url中要传入的参数 #(?P<version>[v1|v2]+)/users/,这里本来需要传version的参数,但是version包含在request里面,所有只需要request=request就可以 url_path=request.versioning_scheme.reverse(viewname='api_user',request=request) print(url_path) self.dispatch returnHttpResponse('用户列表') #fromrest_framework.parsersimportJSONParser,FormParser classPaserView(APIView): '''解析''' #parser_classes=[JSONParser,FormParser,] #JSONParser:表示只能解析content-type:application/json的头 #FormParser:表示只能解析content-type:application/x-www-form-urlencoded的头 defpost(self,request,*args,**kwargs): #获取解析后的结果 print(request.data) returnHttpResponse('paser') ###########################################序列化########################################################### fromrest_frameworkimportserializers #要先写一个序列化的类 classRolesSerializer(serializers.Serializer): #Role表里面的字段id和title序列化 id=serializers.IntegerField() title=serializers.CharField() classRolesView(APIView): defget(self,request,*args,**kwargs): #方式一:对于[obj,obj,obj] #(Queryset) #roles=models.Role.objects.all() #序列化,两个参数,instance:Queryset如果有多个值,就需要加mangy=True #ser=RolesSerializer(instance=roles,many=True) #转成json格式,ensure_ascii=False表示显示中文,默认为True #ret=json.dumps(ser.data,ensure_ascii=False) #方式二: role=models.Role.objects.all().first() ser=RolesSerializer(instance=role,many=False) ret=json.dumps(ser.data,ensure_ascii=False) returnHttpResponse(ret) #classUserInfoSerializer(serializers.Serializer): #'''序列化用户的信息''' ##user_type是choices(1,2,3),显示全称的方法用source #type=serializers.CharField(source="get_user_type_display") #username=serializers.CharField() #password=serializers.CharField() ##group.title:组的名字 #group=serializers.CharField(source="group.title") ##SerializerMethodField(),表示自定义显示 ##然后写一个自定义的方法 #rls=serializers.SerializerMethodField() # #defget_rls(self,row): ##获取用户所有的角色 #role_obj_list=row.roles.all() #ret=[] ##获取角色的id和名字 ##以字典的键值对方式显示 #foriteminrole_obj_list: #ret.append({"id":item.id,"title":item.title}) #returnret #classUserInfoSerializer(serializers.ModelSerializer): #type=serializers.CharField(source="get_user_type_display") #group=serializers.CharField(source="group.title") #rls=serializers.SerializerMethodField() # #defget_rls(self,row): ##获取用户所有的角色 #role_obj_list=row.roles.all() #ret=[] ##获取角色的id和名字 ##以字典的键值对方式显示 #foriteminrole_obj_list: #ret.append({"id":item.id,"title":item.title}) #returnret # #classMeta: #model=models.UserInfo #fields=['id','username','password','type','group','rls'] #classUserInfoSerializer(serializers.ModelSerializer): #classMeta: #model=models.UserInfo ##fields="__all__" #fields=['id','username','password','group','roles'] ##表示连表的深度 #depth=1 classUserInfoSerializer(serializers.ModelSerializer): group=serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='pk') classMeta: model=models.UserInfo #fields="__all__" fields=['id','username','password','group','roles'] #表示连表的深度 depth=0 classUserInfoView(APIView): '''用户的信息''' defget(self,request,*args,**kwargs): users=models.UserInfo.objects.all() #这里必须要传参数context={'request':request} ser=UserInfoSerializer(instance=users,many=True,context={'request':request}) ret=json.dumps(ser.data,ensure_ascii=False) returnHttpResponse(ret) classGroupSerializer(serializers.ModelSerializer): classMeta: model=models.UserGroup fields="__all__" classGroupView(APIView): defget(self,request,*args,**kwargs): pk=kwargs.get('pk') obj=models.UserGroup.objects.filter(pk=pk).first() ser=GroupSerializer(instance=obj,many=False) ret=json.dumps(ser.data,ensure_ascii=False) returnHttpResponse(ret) ####################################序列化之用户请求数据验证验证#################################### #自定义验证规则 classGroupValidation(object): def__init__(self,base): self.base=base def__call__(self,value): ifnotvalue.startswith(self.base): message="标题必须以%s为开头"%self.base raiseserializers.ValidationError(message) classUserGroupSerializer(serializers.Serializer): title=serializers.CharField(validators=[GroupValidation('以我开头'),]) classUserGroupView(APIView): defpost(self,request,*args,**kwargs): ser=UserGroupSerializer(data=request.data) ifser.is_valid(): print(ser.validated_data['title']) else: print(ser.errors) returnHttpResponse("用户提交数据验证") ##################################################分页################################################### fromapi.utils.serializsers.pagerimportPagerSerialiser fromrest_framework.responseimportResponse fromrest_framework.paginationimportPageNumberPagination,LimitOffsetPagination,CursorPagination ##自定义分页类1 #classMyPageNumberPagination(PageNumberPagination): ##每页显示多少个 #page_size=3 ##默认每页显示3个,可以通过传入pager1/?page=2&size=4,改变默认每页显示的个数 #page_size_query_param="size" ##最大页数不超过10 #max_page_size=10 ##获取页码数的 #page_query_param="page" #自定义分页类2 classMyLimitOffsetPagination(LimitOffsetPagination): #默认显示的个数 default_limit=2 #当前的位置 offset_query_param="offset" #通过limit改变默认显示的个数 limit_query_param="limit" #一页最多显示的个数 max_limit=10 #自定义分页类3(加密分页) classMyCursorPagination(CursorPagination): cursor_query_param="cursor" page_size=2#每页显示2个数据 ordering='id'#排序 page_size_query_param=None max_page_size=None classPager1View(APIView): defget(self,request,*args,**kwargs): #获取所有数据 roles=models.Role.objects.all() #创建分页对象 pg=MyCursorPagination() #获取分页的数据 page_roles=pg.paginate_queryset(queryset=roles,request=request,view=self) #对数据进行序列化 ser=PagerSerialiser(instance=page_roles,many=True) returnResponse(ser.data) #returnpg.get_paginated_response(ser.data)
#api/utils/serializsers/pager.py fromrest_frameworkimportserializers fromapiimportmodels classPagerSerialiser(serializers.ModelSerializer): classMeta: model=models.Role fields="__all__"
看完上述内容,你们对如何在Django中使用rest framework实现分页有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注恰卡编程网行业资讯频道,感谢大家的支持。
推荐阅读
-
浅析Django接口版本控制
-
Django+Celery实现定时任务的示例
-
Python(django中如何使用restful框架)
-
Django实现drf搜索过滤和排序过滤
-
Django中怎么将ValuesQuerySet转换成json
今天就跟大家聊聊有关Django中怎么将ValuesQuerySet转换成json,可能很多人都不太了解,为了让大家更加了解,小编...
-
Django分页器的使用方法
这篇文章主要介绍了Django分页器的使用方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面...
-
Python Django搭建文件下载服务器的实现shili
-
在Django中如何使用MQTT的方法
这篇文章主要介绍了在Django中如何使用MQTT的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有...
-
Django开发RESTful API怎么实现增删改查
-
Django如何显示可视化图表的实践