标签:数字 mod 执行 课程 流程 clu 指定 注意 tail
先创建一个django项目,在项目中创建一些表,用来测试rest framework的各种组件
models.py
class UserInfo(models.Model): """用户信息表""" user = models.CharField(max_length=32) pwd = models.CharField(max_length=32) class UserToken(models.Model): """用户token表""" user = models.OneToOneField(to="UserInfo", on_delete=models.CASCADE) token = models.CharField(max_length=64) class Courses(models.Model): """ 课程表 """ name = models.CharField(verbose_name="课程名称", max_length=32) course_img = models.CharField(verbose_name="课程图片", max_length=64) level_choices = ( (1, "初级"), (2, "中级"), (3, "高级"), ) level = models.IntegerField(verbose_name="难度", choices=level_choices, default=1) def __str__(self): return self.name class CourseDetail(models.Model): """课程详细表""" course = models.OneToOneField(to="Courses", on_delete=models.CASCADE) slogan = models.CharField(verbose_name="口号", max_length=255) why = models.CharField(verbose_name="为什么要学", max_length=255) recommend_courses = models.ManyToManyField(verbose_name="推荐课程", to="Courses", related_name="rc") # related_name设置反向查询的字段,有多个关联时指定某个字段进行反向查询 def __str__(self): return "课程详细:" + self.course.title class Chapter(models.Model): """ 课程章节表 """ num = models.IntegerField(verbose_name="章节") name = models.CharField(verbose_name="章节名称", max_length=32) course = models.ForeignKey(verbose_name="所属课程", to="Courses", related_name=‘coursechapters‘, on_delete=models.CASCADE) def __str__(self): return self.name
urls.py
from django.contrib import admin from django.urls import path, include, re_path urlpatterns = [ path(‘admin/‘, admin.site.urls), re_path(r‘^api/(?P<version>\w+)/‘, include("api.urls")), ]
api/urls.py
from django.urls import re_path
from api.views import courses, account, micro
urlpatterns = [
re_path(r‘^courses/$‘, courses.CoursesView.as_view({"get": "list"})),
re_path(r‘^courses/(?P<pk>\d+)/‘, courses.CoursesView.as_view({"get": "retrieve"})),
re_path(r‘^micro/$‘, micro.MicroView.as_view({"get": "list"})),
re_path(r‘^login/$‘, account.LoginView.as_view()),
]
请求到来之后,都要执行dispatch方法,dispatch方法根据请求方式不同触发不同的方法,返回不同的内容
url.py
1 from django.conf.urls import url, include 2 from api.views import TestView 3 4 urlpatterns = [ 5 url(r‘^test/‘, TestView.as_view()), 6 ]
views.py
1 from rest_framework.views import APIView 2 from rest_framework.response import Response 3 4 5 class TestView(APIView): 6 def dispatch(self, request, *args, **kwargs): 7 """ 8 请求到来之后,都要执行dispatch方法,dispatch方法根据请求方式不同触发 get/post/put等方法 9 10 注意:dispatch方法有好多好多的功能 11 """ 12 return super().dispatch(request, *args, **kwargs) 13 14 def get(self, request, *args, **kwargs): 15 return Response(‘GET请求,响应内容‘) 16 17 def post(self, request, *args, **kwargs): 18 return Response(‘POST请求,响应内容‘) 19 20 def put(self, request, *args, **kwargs): 21 return Response(‘PUT请求,响应内容‘)
给micro添加需要认证才能访问的权限
micro.py
# _*_ coding=utf-8 _*_ from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.viewsets import ViewSetMixin from api.auth.auth import MicroAuth class MicroView(ViewSetMixin, APIView): # 给micro添加认证后才能访问的组件 authentication_classes = [MicroAuth] def list(self, request, *args, **kwargs): ret = {‘code‘: 1000, ‘data‘: ‘学习中心‘} return Response(ret)
auth.py
# _*_ coding=utf-8 _*_ from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from api.models import * class MicroAuth(BaseAuthentication): """从token表读取token进行认证""" def authenticate(self, request): token = request.query_params.get(‘token‘) obj = UserToken.objects.filter(token=token).first() if not obj: raise AuthenticationFailed({‘code‘: 10001, ‘error‘: ‘认证失败‘}) return (obj.user.user, obj)
全局设置:
上述操作中均是对单独视图进行特殊配置,如果想要对全局进行配置,则需要再配置文件中写入即可
给course添加频率限制,同一个IP,60秒内访问不超过3次
?使用自定义类进行访问频率控制,继承BaseThrottle类
myThrottle.py
import time from rest_framework.throttling import BaseThrottle class MyThrottle(BaseThrottle): """IP访问频率组件 限制60秒内访问3次""" def __init__(self): self.history = None def allow_request(self, request, view): current_time = time.time() ip = request.META.get(‘REMOTE_ADDR‘) print(ip) if ip not in visit_code: # 如果是第一次访问就把此ip的访问时间存入visit_code中,返回True,不限制 visit_code[ip] = [current_time, ] return True # 如果不是第一次访问,就获取其ip的访问时间[time1,time2..] history = visit_code.get(ip) self.history = history # print(history,visit_code) while history and history[-1] < current_time - 60: # 判断第一次访问时间和当前时间是否超过60s,超过则删除 history.pop() if len(history) < 3: # history里面的元素小于3个则把当前时间添加进去,方法True history.insert(0, current_time) return True # else: # 可以不写 # return False def wait(self): """需要等待多少时间才能访问""" current_time = time.time() return 60 - (current_time - self.history[-1])
在CoursesView类添加访问频率组件
class CoursesView(ViewSetMixin, APIView): # 频率访问组件 throttle_classes = [MyThrottle,]
?使用rest framework内置频率控制组件
myThrottle.py
from rest_framework.throttling import SimpleRateThrottle class VisitThrottle(SimpleRateThrottle): """内置ip频率组件,需要在settings里面设置参数""" scope = "visit_rate" def get_cache_key(self, request, view): return self.get_ident(request)
settings.py
REST_FRAMEWORK = { "DEFAULT_THROTTLE_CLASSES": ["api.myThrottle.VisitThrottle", ], "DEFAULT_THROTTLE_RATES": { "visit_rate": "5/m", # 这个参数就是频率类中定义的那个参数scope, 其中第一个数字5表示5次, # 后面的m表示一分钟,还有s,一秒, h, 一小时, d, 一天 } }
标签:数字 mod 执行 课程 流程 clu 指定 注意 tail
原文地址:https://www.cnblogs.com/zivli/p/10339945.html