django rest_framework 框架的使用02

rest_framework 訪問頻率的限制(節流)

對於用戶訪問頻率的顯示,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",]
rest_framework版本控制

首先是本身寫在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
        )
相關文章
相關標籤/搜索