一、权限组件
-
局部权限检测
models 额外添加class User(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) type_choices=((1,"普通用户"),(2,"VIP"),(3,"SVIP")) user_type=models.IntegerField(choices=type_choices,default=1) class Token(models.Model): user=models.OneToOneField("User") token = models.CharField(max_length=128) def __str__(self): return self.token
class SVIPPermission(object): message="只有超级用户才能访问" def has_permission(self,request,view): username=request.user user_type=User.objects.filter(name=username).first().user_type if user_type==3: return True # 通过权限认证 else: return False class AuthorModelView(viewsets.ModelViewSet): permission_classes=[SVIPPermission,] queryset = Author.objects.all() serializer_class = AuthorModelSerializers
-
全局权限检测
app01/utils.py/下添加 SVIPPermission类(名字可以自己定义)
class SVIPPermission(object): message="只有超级用户才能访问" def has_permission(self,request,view): username=request.user user_type=User.objects.filter(name=username).first().user_type if user_type==3: return True # 通过权限认证 else: return False setting.py下添加部分 REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES": ["app01.utils.SVIPPermission",], } views.py class AuthorModelView(viewsets.ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorModelSerializers
二、 频率组件
-
局部添加频率组件
定义的频率筛选的类
import time from rest_framework.throttling import BaseThrottle class MyThrottle(BaseThrottle): visited_record = {} def __init__(self): self.history = None def allow_request(self, request, my_cbv): # 这个my_cbv是源码中传的我们的视图类,这里我们也要传进去 # print(self.get_ident(request)) # 可以获取本次请求的ip ip = request.META.get("REMOTE_ADDR") #获取本次访问的ip地址 if ip not in self.visited_record: self.visited_record[ip] = [] current_time = time.time() history = self.visited_record[ip] self.history = history print(history) while history and current_time - history[-1] > 60: # 把大于60秒的时间都删掉 history.pop() if len(history) > 2: # 第三次访问,列表中只有2个值,也满足条件 return False history.insert(0, current_time) return True def wait(self): """ 用于返回还剩多少时间访问; 本次访问时间:9:50:55 [09:50:30, 09:50:20, 09:50:10] 剩余 60 - (9:50:55 - 09:50:10)秒才能访问 :return: """ c_time = time.time() return 60 - (c_time - self.history[-1])
视图类
class BookView(generics.GenericAPIView, ListModelMixin, CreateModelMixin): queryset = models.Book.objects.all() serializer_class = BookSerializer authentication_classes = [UserAuth] permission_classes = [VipPermission] throttle_classes = [MyThrottle] def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs)
2. 全局添加频率组件
setting.pyREST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( 'app01.utils.throttle_class.MyThrottle', ), }
3. 使用内置频率组件
频率类
from rest_framework.throttling import SimpleRateThrottle class MyThrottle(SimpleRateThrottle): scope = "visit_rate" # 这个值决定了在配置时使用那个变量描述限制的频率 def get_cache_key(self, request, view): # 这个方法也是必须要有 return self.get_ident(request)
这次只能在setttings中配置
REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( 'app01.utils.throttle_class.MyThrottle', ), "DEFAULT_THROTTLE_RATES": { "visit_rate": "10/m", # 这个参数就是频率类中定义的那个参数scope, 其中第一个数字10表示10次,后面的m表示一分钟,还有s,一秒, h, 一小时, d, 一天 } }
三、解析器(出自https://www.cnblogs.com/neymargoal/p/9796438.html)
-
什么是解析器(what):
根据请求头 content-type 选择对应的解析器对请求体内容进行处理,有application/json,x-www-form-urlencoded,form-data等格式
-
局部视图
from django.conf.urls import url, include from web.views.s5_parser import TestView urlpatterns = [ url(r'test/', TestView.as_view(), name='test'), ]
1.仅处理请求头
content-type
为application/json
的请求体from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import JSONParser class TestView(APIView): parser_classes = [JSONParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容')
2.仅处理请求头
content-type
为application/x-www-form-urlencoded
的请求体from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import FormParser class TestView(APIView): parser_classes = [FormParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容')
3.仅处理请求头
content-type
为multipart/form-data
的请求体from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import MultiPartParser class TestView(APIView): parser_classes = [MultiPartParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容')
对应html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data"> <input type="text" name="user" /> <input type="file" name="img"> <input type="submit" value="提交"> </form> </body> </html>
4.仅上传文件
from django.conf.urls import url, include from web.views import TestView urlpatterns = [ url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'), ]
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import FileUploadParser class TestView(APIView): parser_classes = [FileUploadParser, ] def post(self, request, filename, *args, **kwargs): print(filename) print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容')
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data"> <input type="text" name="user" /> <input type="file" name="img"> <input type="submit" value="提交"> </form> </body> </html>
5.同时多个Parser(当同时使用多个parser时,rest framework会根据请求头content-type自动进行比对,并使用对应parser)
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import JSONParser, FormParser, MultiPartParser class TestView(APIView): parser_classes = [JSONParser, FormParser, MultiPartParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容')
-
全局视图
urlpatterns = [ url(r'test/', TestView.as_view()), ]
REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser' 'rest_framework.parsers.FormParser' 'rest_framework.parsers.MultiPartParser' ] }
from rest_framework.views import APIView from rest_framework.response import Response class TestView(APIView): def post(self, request, *args, **kwargs): print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容')
四、添加版本
-
添加配置(setting.py)
REST_FRAMEWORK = { .... 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', 'ALLOWED_VERSIONS':['v1','v2'], # 允许的版本 'VERSION_PARAM':'version', # 参数 'DEFAULT_VERSION':'v1', # 默认版本 .... }
-
设置路由
s9luffycity/urls.py
urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^api/(?P<version>\w+)/', include('api.urls')), ]
api/urls.py
urlpatterns = [ url(r'^course/$', course.CourseView.as_view()), ]
-
获取版本
request.version
: 获取版本