wordpress开放多站点,网站做显卡评测软件,淘宝网官方网站网页版,织梦后台怎么做网站地图目录导航 一、RESTful 规范 二、APIView 组件 三、序列化组件 四、认证组件 五、权限组件 六、频率组件 七、分页器组件 一、RESTful 规范 什么是RESTful规范#xff1a; REST与技术无关#xff0c;代表的是一种软件架构风格#xff0c;REST是Representational State Transf… 目录导航 一、RESTful 规范 二、APIView 组件 三、序列化组件 四、认证组件 五、权限组件 六、频率组件 七、分页器组件 一、RESTful 规范 什么是RESTful规范 REST与技术无关代表的是一种软件架构风格REST是Representational State Transfer的简称中文翻译为“表征状态转移” REST从资源的角度类审视整个网络它将分布在网络中某个节点的资源通过URL进行标识客户端应用通过URL来获取资源的表征获得这些表征致使这些应用转变状态 REST与技术无关代表的是一种软件架构风格REST是Representational State Transfer的简称中文翻译为“表征状态转移” 所有的数据不过是通过网络获取的还是操作增删改查的数据都是资源将一切数据视为资源是REST区别与其他架构风格的最本质属性 对于REST这种面向资源的架构风格有人提出一种全新的结构理念即面向资源架构ROAResource Oriented Architecture RESTful API 设计 API与用户的通信协议总是使用HTTPs协议。 域名 https://api.example.com 尽量将API部署在专用域名会存在跨域问题https://example.org/api/ API很简单 版本 URL如https://api.example.com/v1/请求头 跨域时引发发送多次请求 路径视网络上任何东西都是资源均使用名词表示可复数 https://api.example.com/v1/zooshttps://api.example.com/v1/animalshttps://api.example.com/v1/employees method GET 从服务器取出资源一项或多项POST 在服务器新建一个资源PUT 在服务器更新资源客户端提供改变后的完整资源PATCH 在服务器更新资源客户端提供改变的属性DELETE 从服务器删除资源 过滤通过在url上传参的形式传递搜索条件 https://api.example.com/v1/zoos?limit10指定返回记录的数量https://api.example.com/v1/zoos?offset10指定返回记录的开始位置https://api.example.com/v1/zoos?page2per_page100指定第几页以及每页的记录数https://api.example.com/v1/zoos?sortbynameorderasc指定返回结果按照哪个属性排序以及排序顺序https://api.example.com/v1/zoos?animal_type_id1指定筛选条件 状态码 200 OK - [GET]服务器成功返回用户请求的数据该操作是幂等的Idempotent。201 CREATED - [POST/PUT/PATCH]用户新建或修改数据成功。202 Accepted - [*]表示一个请求已经进入后台排队异步任务204 NO CONTENT - [DELETE]用户删除数据成功。400 INVALID REQUEST - [POST/PUT/PATCH]用户发出的请求有错误服务器没有进行新建或修改数据的操作该操作是幂等的。401 Unauthorized - [*]表示用户没有权限令牌、用户名、密码错误。403 Forbidden - [*] 表示用户得到授权与401错误相对但是访问是被禁止的。404 NOT FOUND - [*]用户发出的请求针对的是不存在的记录服务器没有进行操作该操作是幂等的。406 Not Acceptable - [GET]用户请求的格式不可得比如用户请求JSON格式但是只有XML格式。410 Gone -[GET]用户请求的资源被永久删除且不会再得到的。422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时发生一个验证错误。500 INTERNAL SERVER ERROR - [*]服务器发生错误用户将无法判断发出的请求是否成功。更多看这里http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 错误处理应返回错误信息error当做key。 返回结果针对不同操作服务器向用户返回的结果应该符合以下规范。 GET /collection返回资源对象的列表数组 GET /collection/resource返回单个资源对象 POST /collection返回新生成的资源对象 PUT /collection/resource返回完整的资源对象 PATCH /collection/resource返回完整的资源对象 DELETE /collection/resource返回一个空文档 Hypermedia APIRESTful API最好做到Hypermedia即返回结果中提供链接连向其他API方法使得用户不查文档也知道下一步应该做什么。 {link: { rel: collection https://www.example.com/zoos, href: https://api.example.com/zoos, title: List of zoos, type: application/vnd.yourformatjson }} 基于Django实现 1 urlpatterns [
2 url(r^users/$, views.Users.as_view()),
3 url(r^users2/$, views.user2),
4
5 ] 路由系统配置 1 import json2 3 def user2(request):4 if request.methodGET:5 dic {status:200,name: lqz2, age: 18}6 return HttpResponse(json.dumps(dic))7 elif request.methodPOST:8 dic {status: 200, msg: 修改成功}9 return JsonResponse(dic)
10
11 class Users(View):
12 def get(self, request):
13 dic {status:200,name: lqz, age: 18}
14 return HttpResponse(json.dumps(dic))
15
16 def post(self, request):
17 dic {status: 200, msg: 修改成功}
18 return JsonResponse(dic) views.py 二、APIView 组件 安装djangorestframework 方式一pip3 install djangorestframework方式二pycharm图形化界面安装方式三pycharm命令行下安装装在当前工程所用的解释器下 djangorestframework的APIView分析 1 classmethod2 def as_view(cls, **initkwargs):3 4 Store the original class on the view function.5 6 This allows us to discover information about the view when we do URL7 reverse lookups. Used for breadcrumb generation.8 9 if isinstance(getattr(cls, queryset, None), models.query.QuerySet):
10 def force_evaluation():
11 raise RuntimeError(
12 Do not evaluate the .queryset attribute directly,
13 as the result will be cached and reused between requests.
14 Use .all() or call .get_queryset() instead.
15 )
16 cls.queryset._fetch_all force_evaluation
17
18 view super(APIView, cls).as_view(**initkwargs)
19 view.cls cls
20 view.initkwargs initkwargs
21
22 # Note: session based authentication is explicitly CSRF validated,
23 # all other authentication is CSRF exempt.
24 return csrf_exempt(view) as_view方法 1 def dispatch(self, request, *args, **kwargs):2 3 .dispatch() is pretty much the same as Djangos regular dispatch,4 but with extra hooks for startup, finalize, and exception handling.5 6 self.args args7 self.kwargs kwargs8 request self.initialize_request(request, *args, **kwargs)9 self.request request
10 self.headers self.default_response_headers # deprecate?
11
12 try:
13 self.initial(request, *args, **kwargs)
14
15 # Get the appropriate handler method
16 if request.method.lower() in self.http_method_names:
17 handler getattr(self, request.method.lower(),
18 self.http_method_not_allowed)
19 else:
20 handler self.http_method_not_allowed
21
22 response handler(request, *args, **kwargs)
23
24 except Exception as exc:
25 response self.handle_exception(exc)
26
27 self.response self.finalize_response(request, response, *args, **kwargs)
28 return self.response dispatch def initialize_request(self, request, *args, **kwargs):Returns the initial request object.parser_context self.get_parser_context(request)return Request(request,parsersself.get_parsers(),authenticatorsself.get_authenticators(),negotiatorself.get_content_negotiator(),parser_contextparser_context) initialize_request 1 def initial(self, request, *args, **kwargs):2 3 Runs anything that needs to occur prior to calling the method handler.4 5 self.format_kwarg self.get_format_suffix(**kwargs)6 7 # Perform content negotiation and store the accepted info on the request8 neg self.perform_content_negotiation(request)9 request.accepted_renderer, request.accepted_media_type neg
10
11 # Determine the API version, if versioning is in use.
12 version, scheme self.determine_version(request, *args, **kwargs)
13 request.version, request.versioning_scheme version, scheme
14
15 # Ensure that the incoming request is permitted
16 self.perform_authentication(request)
17 self.check_permissions(request)
18 self.check_throttles(request) initial方法内部调用认证权限和频率 三、序列化组件 rest-framework序列化之Serializer 1 from django.db import models2 3 # Create your models here.4 5 6 class Book(models.Model):7 titlemodels.CharField(max_length32)8 pricemodels.IntegerField()9 pub_datemodels.DateField()
10 publishmodels.ForeignKey(Publish)
11 authorsmodels.ManyToManyField(Author)
12 def __str__(self):
13 return self.title
14
15 class Publish(models.Model):
16 namemodels.CharField(max_length32)
17 emailmodels.EmailField()
18 def __str__(self):
19 return self.name
20
21 class Author(models.Model):
22 namemodels.CharField(max_length32)
23 agemodels.IntegerField()
24 def __str__(self):
25 return self.name models.py 1 from rest_framework.views import APIView2 from rest_framework.response import Response3 from .models import *4 from django.shortcuts import HttpResponse5 from django.core import serializers6 7 8 from rest_framework import serializers9
10 class BookSerializers(serializers.Serializer):
11 titleserializers.CharField(max_length32)
12 priceserializers.IntegerField()
13 pub_dateserializers.DateField()
14 publishserializers.CharField(sourcepublish.name)
15 #authorsserializers.CharField(sourceauthors.all)
16 authorsserializers.SerializerMethodField()
17 def get_authors(self,obj):
18 temp[]
19 for author in obj.authors.all():
20 temp.append(author.name)
21 return temp
22 #此处可以继续用author的Serializers
23 # def get_authors(self,obj):
24 # retobj.authors.all()
25 # ssAuthorSerializer(ret,manyTrue)
26 # return ss.data
27
28 class BookViewSet(APIView):
29
30 def get(self,request,*args,**kwargs):
31 book_listBook.objects.all()
32 # 序列化方式1:
33 # from django.forms.models import model_to_dict
34 # import json
35 # data[]
36 # for obj in book_list:
37 # data.append(model_to_dict(obj))
38 # print(data)
39 # return HttpResponse(ok)
40
41 # 序列化方式2:
42 # dataserializers.serialize(json,book_list)
43 # return HttpResponse(data)
44
45 # 序列化方式3:
46 bsBookSerializers(book_list,manyTrue) #manyTrue代表有多条数据如果只有一条数据manyFalse
47 return Response(bs.data)
48 # 序列化方式4:
49 # retmodels.Book.objects.all().values(nid,title)
50 # ddlist(ret)
51 # return HttpResponse(json.dumps(dd)) views.py 注意 source 如果是字段会显示字段如果是方法会执行方法不用加括号authorsserializers.CharField(sourceauthors.all)如在模型中定义一个方法直接可以在在source指定执行 class UserInfo(models.Model):user_type_choices ((1,普通用户),(2,VIP),(3,SVIP),)user_type models.IntegerField(choicesuser_type_choices)username models.CharField(max_length32,uniqueTrue)password models.CharField(max_length64)#视图
retmodels.UserInfo.objects.filter(pk1).first()
aaret.get_user_type_display()#serializer
xxserializers.CharField(sourceget_user_type_display) View Code rest-framework序列化之ModelSerializer 1 class BookSerializers(serializers.ModelSerializer):2 class Meta:3 model models.Book4 # fields __all__5 fields[nid,title,authors,publish]6 # exclude(nid,) #不能跟fields同时用7 # depth 1 #深度控制写 几 往里拿几层层数越多响应越慢官方建议0--10之间个人建议最多3层8 publishserializers.SerializerMethodField()9 def get_publish(self,obj):
10 return obj.publish.name
11 authorsserializers.SerializerMethodField()
12 def get_authors(self,obj):
13 retobj.authors.all()
14 ssAuthorSerializer(ret,manyTrue)
15 return ss.data 生成hypermedialink极少数 1 class BookSerializers(serializers.ModelSerializer):2 class Meta:3 model models.Book4 fields __all__5 # 生成连接直接查看出版社详情6 publish serializers.HyperlinkedIdentityField(view_namettt, lookup_fieldpublish_id, lookup_url_kwargpkk)7 authorsserializers.SerializerMethodField()8 def get_authors(self,obj):9 retobj.authors.all()
10 ssAuthorSerializer(ret,manyTrue)
11 return ss.data
12 #--------------
13
14 resBookSerializers(ret,manyTrue,context{request: request})
15
16 #--------------
17
18 class Publish(APIView):
19 def get(self,request,pkk):
20 print(pkk)
21 return HttpResponse(ok)
22 #----路由---
23 url(r^publish/(?Ppkk\d)$, views.Publish.as_view(),namettt), 序列化组件之请求数据校验和保存功能 class BookSerializers(serializers.ModelSerializer):class Meta:modelBookfields__all__#————————
class BookView(APIView):def post(self, request):# 添加一条数据print(request.data)bsBookSerializers(datarequest.data)if bs.is_valid():bs.save() # 生成记录return Response(bs.data)else:return Response(bs.errors) class BookSerializer1(serializers.Serializer):titleserializers.CharField(error_messages{required: 标题不能为空})#这种方式要保存必须重写create方法 通过源码查看留的校验字段的钩子函数 1 #is_valid----self.run_validation-(执行Serializer的run_validation)--self.to_internal_value(data)---执行Serializer的run_validation485行2 def validate_title(self, value):3 from rest_framework import exceptions4 raise exceptions.ValidationError(看你不顺眼)5 return value6 7 #全局8 def validate(self, attrs):9 from rest_framework import exceptions
10 if attrs.get(title) attrs.get(title2):
11 return attrs
12 else:
13 raise exceptions.ValidationError(不想等啊) 序列化组件源码分析 1
2 序列化组件先调用__new__方法如果manyTrue生成ListSerializer对象如果为False生成Serializer对象
3 序列化对象.data方法--调用父类data方法---调用对象自己的to_representation自定义的序列化类无此方法去父类找
4 Aerializer类里有to_representation方法for循环执行attribute field.get_attribute(instance)
5 再去Field类里去找get_attribute方法self.source_attrs就是被切分的source然后执行get_attribute方法source_attrs
6 当参数传过去判断是方法就加括号执行是属性就把值取出来
7 图书的增删查改resful接口 1 class BookSerializers(serializers.ModelSerializer):2 class Meta:3 modelmodels.Book4 fields__all__5 6 7 class BookView(APIView):8 9 def get(self, request):
10 book_list models.Book.objects.all()
11 bs BookSerializers(book_list, manyTrue)
12 # 序列化数据
13
14 return Response(bs.data)
15
16 def post(self, request):
17 # 添加一条数据
18 print(request.data)
19
20 bsBookSerializers(datarequest.data)
21 if bs.is_valid():
22 bs.save() # 生成记录
23 return Response(bs.data)
24 else:
25
26 return Response(bs.errors)
27
28 class BookDetailView(APIView):
29 def get(self,request,pk):
30 book_objmodels.Book.objects.filter(pkpk).first()
31 bsBookSerializers(book_obj,manyFalse)
32 return Response(bs.data)
33 def put(self,request,pk):
34 book_obj models.Book.objects.filter(pkpk).first()
35
36 bsBookSerializers(datarequest.data,instancebook_obj)
37 if bs.is_valid():
38 bs.save() # update
39 return Response(bs.data)
40 else:
41 return Response(bs.errors)
42 def delete(self,request,pk):
43 models.Book.objects.filter(pkpk).delete()
44
45 return Response() views.py 1 url(r^books/$, views.BookView.as_view()),
2 url(r^books/(?Ppk\d)$, views.BookDetailView.as_view()), urls.py 四、认证组件 认证简介 只有认证通过的用户才能访问指定的url地址比如查询课程信息需要登录之后才能查看没有登录就不能查看这时候需要用到认证组件 局部使用 1 class User(models.Model):
2 usernamemodels.CharField(max_length32)
3 passwordmodels.CharField(max_length32)
4 user_typemodels.IntegerField(choices((1,超级用户),(2,普通用户),(3,二笔用户)))
5
6 class UserToken(models.Model):
7 usermodels.OneToOneField(toUser)
8 tokenmodels.CharField(max_length64) models.py 1 from rest_framework.authentication import BaseAuthentication2 class TokenAuth():3 def authenticate(self, request):4 token request.GET.get(token)5 token_obj models.UserToken.objects.filter(tokentoken).first()6 if token_obj:7 return8 else:9 raise AuthenticationFailed(认证失败)
10 def authenticate_header(self,request):
11 pass 新建认证类验证通过return两个参数 1 def get_random(name):2 import hashlib3 import time4 mdhashlib.md5()5 md.update(bytes(str(time.time()),encodingutf-8))6 md.update(bytes(name,encodingutf-8))7 return md.hexdigest()8 class Login(APIView):9 def post(self,reuquest):
10 back_msg{status:1001,msg:None}
11 try:
12 namereuquest.data.get(name)
13 pwdreuquest.data.get(pwd)
14 usermodels.User.objects.filter(usernamename,passwordpwd).first()
15 if user:
16 tokenget_random(name)
17 models.UserToken.objects.update_or_create(useruser,defaults{token:token})
18 back_msg[status]1000
19 back_msg[msg]登录成功
20 back_msg[token]token
21 else:
22 back_msg[msg] 用户名或密码错误
23 except Exception as e:
24 back_msg[msg]str(e)
25 return Response(back_msg)
26
27
28
29 class Course(APIView):
30 authentication_classes [TokenAuth, ]
31
32 def get(self, request):
33 return HttpResponse(get)
34
35 def post(self, request):
36 return HttpResponse(post) views.py 1 def get_token(id,salt123):2 import hashlib3 mdhashlib.md5()4 md.update(bytes(str(id),encodingutf-8))5 md.update(bytes(salt,encodingutf-8))6 7 return md.hexdigest()|str(id)8 9 def check_token(token,salt123):
10 lltoken.split(|)
11 import hashlib
12 mdhashlib.md5()
13 md.update(bytes(ll[-1],encodingutf-8))
14 md.update(bytes(salt,encodingutf-8))
15 if ll[0]md.hexdigest():
16 return True
17 else:
18 return False
19
20 class TokenAuth():
21 def authenticate(self, request):
22 token request.GET.get(token)
23 successcheck_token(token)
24 if success:
25 return
26 else:
27 raise AuthenticationFailed(认证失败)
28 def authenticate_header(self,request):
29 pass
30 class Login(APIView):
31 def post(self,reuquest):
32 back_msg{status:1001,msg:None}
33 try:
34 namereuquest.data.get(name)
35 pwdreuquest.data.get(pwd)
36 usermodels.User.objects.filter(usernamename,passwordpwd).first()
37 if user:
38 tokenget_token(user.pk)
39 # models.UserToken.objects.update_or_create(useruser,defaults{token:token})
40 back_msg[status]1000
41 back_msg[msg]登录成功
42 back_msg[token]token
43 else:
44 back_msg[msg] 用户名或密码错误
45 except Exception as e:
46 back_msg[msg]str(e)
47 return Response(back_msg)
48 from rest_framework.authentication import BaseAuthentication
49 class TokenAuth():
50 def authenticate(self, request):
51 token request.GET.get(token)
52 token_obj models.UserToken.objects.filter(tokentoken).first()
53 if token_obj:
54 return
55 else:
56 raise AuthenticationFailed(认证失败)
57 def authenticate_header(self,request):
58 pass
59
60 class Course(APIView):
61 authentication_classes [TokenAuth, ]
62
63 def get(self, request):
64 return HttpResponse(get)
65
66 def post(self, request):
67 return HttpResponse(post) 不存数据库的token验证 总结局部使用只需要在视图类里加入 authentication_classes [TokenAuth, ] 全局使用 REST_FRAMEWORK{DEFAULT_AUTHENTICATION_CLASSES:[app01.service.auth.Authentication,]
} 源码分析 1 #Request对象的user方法2 property3 def user(self):4 the authentication classes provided to the request.5 if not hasattr(self, _user):6 with wrap_attributeerrors():7 self._authenticate()8 return self._user9
10 def _authenticate(self):
11 for authenticator in self.authenticators:
12 try:
13 user_auth_tuple authenticator.authenticate(self)
14 except exceptions.APIException:
15 self._not_authenticated()
16 raise
17 #认证成功可以返回一个元组但必须是最后一个验证类才能返回
18 if user_auth_tuple is not None:
19 self._authenticator authenticator
20 self.user, self.auth user_auth_tuple
21 return
22
23 self._not_authenticated() View Code self.authenticators def get_authenticators(self):return [auth() for auth in self.authentication_classes] 认证类使用顺序先用视图类中的验证类再用settings里配置的验证类最后用默认的验证类 五、权限组件 权限简介 只用超级用户才能访问指定的数据普通用户不能访问所以就要有权限组件对其限制 局部使用 1 from rest_framework.permissions import BasePermission2 class UserPermission(BasePermission):3 message 不是超级用户查看不了4 def has_permission(self, request, view):5 # user_type request.user.get_user_type_display()6 # if user_type 超级用户:7 user_type request.user.user_type8 print(user_type)9 if user_type 1:
10 return True
11 else:
12 return False
13 class Course(APIView):
14 authentication_classes [TokenAuth, ]
15 permission_classes [UserPermission,]
16
17 def get(self, request):
18 return HttpResponse(get)
19
20 def post(self, request):
21 return HttpResponse(post) View Code 局部使用只需要在视图类里加入 permission_classes [UserPermission,] 全局使用 REST_FRAMEWORK{DEFAULT_AUTHENTICATION_CLASSES:[app01.service.auth.Authentication,],DEFAULT_PERMISSION_CLASSES:[app01.service.permissions.SVIPPermission,]
} 源码分析 1 def check_permissions(self, request):
2 for permission in self.get_permissions():
3 if not permission.has_permission(request, self):
4 self.permission_denied(
5 request, messagegetattr(permission, message, None)
6 ) View Code self.get_permissions() def get_permissions(self):return [permission() for permission in self.permission_classes] 权限类使用顺序先用视图类中的权限类再用settings里配置的权限类最后用默认的权限类 六、频率组件 频率简介 为了控制用户对某个url请求的频率比如一分钟以内只能访问三次 自定义频率类自定义频率规则 自定义的逻辑 #1取出访问者ip
# 2判断当前ip不在访问字典里添加进去并且直接返回True,表示第一次访问在字典里继续往下走
# 3循环判断当前ip的列表有值并且当前时间减去列表的最后一个时间大于60s把这种数据pop掉这样列表中只有60s以内的访问时间
# 4判断当列表小于3说明一分钟以内访问不足三次把当前时间插入到列表第一个位置返回True顺利通过
# 5当大于等于3说明一分钟内访问超过三次返回False验证失败 代码实现 1 class MyThrottles():2 VISIT_RECORD {}3 def __init__(self):4 self.historyNone5 def allow_request(self,request, view):6 #1取出访问者ip7 # print(request.META)8 iprequest.META.get(REMOTE_ADDR)9 import time
10 ctimetime.time()
11 # 2判断当前ip不在访问字典里添加进去并且直接返回True,表示第一次访问
12 if ip not in self.VISIT_RECORD:
13 self.VISIT_RECORD[ip][ctime,]
14 return True
15 self.historyself.VISIT_RECORD.get(ip)
16 # 3循环判断当前ip的列表有值并且当前时间减去列表的最后一个时间大于60s把这种数据pop掉这样列表中只有60s以内的访问时间
17 while self.history and ctime-self.history[-1]60:
18 self.history.pop()
19 # 4判断当列表小于3说明一分钟以内访问不足三次把当前时间插入到列表第一个位置返回True顺利通过
20 # 5当大于等于3说明一分钟内访问超过三次返回False验证失败
21 if len(self.history)3:
22 self.history.insert(0,ctime)
23 return True
24 else:
25 return False
26 def wait(self):
27 import time
28 ctimetime.time()
29 return 60-(ctime-self.history[-1]) View Code 内置频率类及局部使用 写一个类继承自SimpleRateThrottle根据ip限制问要根据用户现在怎么写 1 from rest_framework.throttling import SimpleRateThrottle
2 class VisitThrottle(SimpleRateThrottle):
3 scope luffy
4 def get_cache_key(self, request, view):
5 return self.get_ident(request) 在setting里配置一分钟访问三次 1 REST_FRAMEWORK {
2 DEFAULT_THROTTLE_RATES:{
3 luffy:3/m
4 }
5 } 在视图类里使用 throttle_classes [MyThrottles,] 错误信息的中文提示 1 class Course(APIView):2 authentication_classes [TokenAuth, ]3 permission_classes [UserPermission, ]4 throttle_classes [MyThrottles,]5 6 def get(self, request):7 return HttpResponse(get)8 9 def post(self, request):
10 return HttpResponse(post)
11 def throttled(self, request, wait):
12 from rest_framework.exceptions import Throttled
13 class MyThrottled(Throttled):
14 default_detail 傻逼啊
15 extra_detail_singular 还有 {wait} second.
16 extra_detail_plural 出了 {wait} seconds.
17 raise MyThrottled(wait) View Code 内置频率限制类 BaseThrottle是所有类的基类方法def get_ident(self, request)获取标识其实就是获取ip自定义的需要继承它 AnonRateThrottle未登录用户ip限制需要配合auth模块用 SimpleRateThrottle重写此方法可以实现频率现在不需要咱们手写上面自定义的逻辑 UserRateThrottle:登录用户频率限制这个得配合auth模块来用 ScopedRateThrottle应用在局部视图上的忽略 内置频率类及全局使用 REST_FRAMEWORK {DEFAULT_THROTTLE_CLASSES:[app01.utils.VisitThrottle,],DEFAULT_THROTTLE_RATES:{luffy:3/m}
} 源码分析 省略。。。。。。 七、分页器组件 简单分页查看第n页每页显示n条 1 from rest_framework.pagination import PageNumberPagination2 # 一 基本使用urlurlhttp://127.0.0.1:8000/pager/?page2size3size无效3 class Pager(APIView):4 def get(self,request,*args,**kwargs):5 # 获取所有数据6 retmodels.Book.objects.all()7 # 创建分页对象8 pagePageNumberPagination()9 # 在数据库中获取分页的数据
10 page_listpage.paginate_queryset(ret,request,viewself)
11 # 对分页进行序列化
12 serBookSerializer1(instancepage_list,manyTrue)
13 return Response(ser.data)
14 # 二 自定制 urlhttp://127.0.0.1:8000/pager/?page2size3
15 # size30无效最多5条
16 class Mypage(PageNumberPagination):
17 page_size 2
18 page_query_param page
19 # 定制传参
20 page_size_query_param size
21 # 最大一页的数据
22 max_page_size 5
23 class Pager(APIView):
24 def get(self,request,*args,**kwargs):
25 # 获取所有数据
26 retmodels.Book.objects.all()
27 # 创建分页对象
28 pageMypage()
29 # 在数据库中获取分页的数据
30 page_listpage.paginate_queryset(ret,request,viewself)
31 # 对分页进行序列化
32 serBookSerializer1(instancepage_list,manyTrue)
33 # return Response(ser.data)
34 # 这个也是返回Response对象但是比基本的多了上一页下一页和总数据条数了解即可
35 return page.get_paginated_response(ser.data) setting中配置 REST_FRAMEWORK {# 每页显示两条PAGE_SIZE:2
} 路由 url(r^pager/$, views.Pager.as_view()), 新建类 Serializers 1 class BookSerializer1(serializers.ModelSerializer):
2 class Meta:
3 modelmodels.Book
4 # fields__all__
5 exclude(authors,) 偏移分页在第n个位置向后查看n条数据 1 # http://127.0.0.1:8000/pager/?offset4limit32 from rest_framework.pagination import LimitOffsetPagination3 # 也可以自定制同简单分页4 class Pager(APIView):5 def get(self,request,*args,**kwargs):6 # 获取所有数据7 retmodels.Book.objects.all()8 # 创建分页对象9 pageLimitOffsetPagination()
10 # 在数据库中获取分页的数据
11 page_listpage.paginate_queryset(ret,request,viewself)
12 # 对分页进行序列化
13 serBookSerializer1(instancepage_list,manyTrue)
14 # return page.get_paginated_response(ser.data)
15 return Response(ser.data) CursorPagination加密分页只能看上一页和下一页速度快 1 from rest_framework.pagination import CursorPagination2 # 看源码是通过sql查询大于id和小于id3 class Pager(APIView):4 def get(self,request,*args,**kwargs):5 # 获取所有数据6 retmodels.Book.objects.all()7 # 创建分页对象8 pageCursorPagination()9 page.orderingnid
10 # 在数据库中获取分页的数据
11 page_listpage.paginate_queryset(ret,request,viewself)
12 # 对分页进行序列化
13 serBookSerializer1(instancepage_list,manyTrue)
14 # 可以避免页码被猜到
15 return page.get_paginated_response(ser.data) 转载于:https://www.cnblogs.com/child-king/p/10456641.html