对于用户访问频率的显示,rest_framework 也有本身的类进行约束json
class VisitControl(BaseThrottle): """ 访问评论限制 """ def __init__(self): self.history = None def allow_request(self, request, view): ctime = time.time() remote_addr = self.get_ident(request) if remote_addr not in VISIT_DICT: VISIT_DICT[remote_addr] = [ctime, ] return True history_list = VISIT_DICT.get(remote_addr) self.history = history_list """ history_list[-1] < ctime - 10 这个--> 若是当前的时间 减去 60秒 以后 与列表里面的 最后一个 就是最先访问的 时间 比较 若是 比他大 证实 这个 时间 无效了 ,把他 去除 ,而后在比较前一个 直到 当前时间 减去60秒以后 比 最后一个小, 证实 这个时间在60秒内,第一个条件就符合了 而后 剩下的 列表里面的值就都符合了(由于 列表里面最前面的元素 时间约靠近当下时间) 而后拿着这个列表里面的值 去判断 (由于这些值都是 60 秒内访问的) 若是小于3 证实 你还有一次机会 让他访问 ,可是 须要 把他加到 列表里面去, 以便下次判断列表个数的时候使用(每次符合要求的时间都须要加到列表里面,共后续使用) """ while history_list and history_list[-1] < ctime - 10: history_list.pop() if len(history_list) < 3: history_list.insert(0, ctime) return True def wait(self): ctime = time.time() return 60 - (ctime - self.history[-1])
其实rest_framework已经为咱们提供了基于用户的节流类,以及基于IP的节流类,咱们只须要继承这个两个类 分别实现各自的方法便可:api
class UserThrottle(SimpleRateThrottle): scope = "User" # 登陆用户访问频率的限制 def get_cache_key(self, request, view): return request.user.username class IpThrottle(SimpleRateThrottle): scope = "AsyUser" # 匿名用户访问频率的限制 def get_cache_key(self, request, view): return self.get_ident(request) """ 注意的是全局的settings配置以下 """ "DEFAULT_AUTHENTICATION_CLASSES": ["api.utils.permission.MyAuthtication",], # 认证全局配置 "DEFAULT_PERMISSION_CLASSES": [], # 权限的 全局配置 # 节流的频率控制 "DEFAULT_THROTTLE_RATES": { "Luffy": "10/m", "User": "20/m" }, # 节流的类,默认是没有的! "DEFAULT_THROTTLE_CLASSES": ["api.utils.permission.UserThrottle",]
首先是本身写在url的get请求的版本控制好比
url="xxxxxx/?version=v1"
对应的类方法以下:app
class MyVersion(BaseVersioning): """ 本身 的类的方法 """ def determine_version(self, request, *args, **kwargs): version = request.query_params.get("version") return version
## 版本的控制的 ## version 是版本号,这个scheme 是你的解析版本的类 ## 解析版本的类只容许有一个 version, scheme = self.determine_version(request, *args, **kwargs) # 版本赋值给 request.version 类赋值给request.versioning_scheme request.version, request.versioning_scheme = version, scheme
通常使用这个内之类便可ide
from rest_framework.versioning import URLPathVersioning class URLPathVersioning(BaseVersioning): """ To the client this is the same style as `NamespaceVersioning`. The difference is in the backend - this implementation uses Django's URL keyword arguments to determine the version. An example URL conf for two views that accept two different versions. urlpatterns = [ url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'), url(r'^(?P<version>[v1|v2]+)/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail') ] GET /1.0/something/ HTTP/1.1 Host: example.com Accept: application/json """ invalid_version_message = _('Invalid version in URL path.') def determine_version(self, request, *args, **kwargs): version = kwargs.get(self.version_param, self.default_version) if not self.is_allowed_version(version): raise exceptions.NotFound(self.invalid_version_message) return version def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra): if request.version is not None: kwargs = {} if (kwargs is None) else kwargs kwargs[self.version_param] = request.version return super(URLPathVersioning, self).reverse( viewname, args, kwargs, request, format, **extra )