国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

詳解django自定義中間件處理

2020-01-04 14:00:58
字體:
來源:轉載
供稿:網友

中間件是一個鉤子框架,它們可以介入 Django 的請求和響應處理過程。 它是一個輕量級、底層的 插件 系統,用于在 全局修改 Django 的輸入或輸出 。

每個中間件組件負責完成某個特定的功能

這里介紹的中間件方法適用于 Django1.10 以上

相關文件: django middleware

Django基礎中間件

django.utils.deprecation.pyclass MiddlewareMixin(object): def __init__(self, get_response=None):  self.get_response = get_response  super(MiddlewareMixin, self).__init__() def __call__(self, request):  response = None  if hasattr(self, 'process_request'):   response = self.process_request(request)  if not response:   response = self.get_response(request)  if hasattr(self, 'process_response'):   response = self.process_response(request, response)  return response

以上為Django基礎中間件源碼,要習慣于看源碼,上面的這段代碼并不復雜,下面我們來一一解釋。

def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__()

熟悉 python 類的都不陌生 __init__ 方法, 這里主要是 一次性配置和初始化

def __call__(self, request):  response = None  if hasattr(self, 'process_request'):    response = self.process_request(request)  if not response:    response = self.get_response(request)  if hasattr(self, 'process_response'):    response = self.process_response(request, response)  return response

__call__ 為每個請求/響應執行的代碼

self.process_request(request) 為每個請求到調用視圖之前的操作,通常可以在這里做一些用戶請求頻率的控制。

self.get_response(request) 為調用視圖

self.process_response(request, response) 為調用視圖完成后的操作

自定義中間件

剛才了解了基礎中間件,現在就開始編寫我們自己的中間件。

通常我們回去繼承基礎中間件來實現自己的功能

from django.utils.deprecation import MiddlewareMixinclass PermissionMiddlewareMixin(MiddlewareMixin):  """  django 中間件  """  def process_request(self, request):    pass  def process_response(self, request, response):    return response

如果你要在請求之前做處理,需要定義 process_request() 方法,去實現相關功能

如果你要在視圖調用之后做處理,需要定義 process_response() 方法,去實現相關功能

:warning:注意 定義 process_response() 方法一定要 return response

需要將你編寫的中間件添加到 settings 中的 MIDDLEWARE 里

我這里寫了一個通過中間件限制客戶端請求頻率,有興趣的可以看一下

django中間件客戶端請求頻率限制

通過redis lua腳本對客戶端IP請求頻率限制

# coding:utf-8__author__ = 'carey@akhack.com'from django.utils.deprecation import MiddlewareMixinfrom django.http.response import HttpResponsefrom django_redis import get_redis_connectionfrom hashlib import md5class RequestBlockMiddlewareMixin(MiddlewareMixin):  """  django中間件客戶端請求頻率限制  """  limit = 4 # 單位時間內允許請求次數  expire = 1 # 限制時間  cache = "default" # 獲取django cache  def process_request(self, request):    num = self.set_key(request)    if num > self.limit:      return HttpResponse("請求頻率過快,請稍后重試", status=503)  @staticmethod  def get_ident(request):    """    Identify the machine making the request by parsing HTTP_X_FORWARDED_FOR    if present and number of proxies is > 0. If not use all of    HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR.    """    NUM_PROXIES = 1    xff = request.META.get('HTTP_X_FORWARDED_FOR')    remote_addr = request.META.get('REMOTE_ADDR')    num_proxies = NUM_PROXIES    if num_proxies is not None:      if num_proxies == 0 or xff is None:        return remote_addr      addrs = xff.split(',')      client_addr = addrs[-min(num_proxies, len(addrs))]      return client_addr.strip()    return ''.join(xff.split()) if xff else remote_addr  def get_md5(self, request):    """    獲取IP md5值    :param request:    :return:    """    ip_str = self.get_ident(request)    ip_md5 = md5()    ip_md5.update(ip_str.encode("utf-8"))    return ip_md5.hexdigest()  def set_key(self, request):    """    通過redis lua腳本設置請求請求次數和限制時間    :param request:    :return: 限制時間內請求次數    """    lua = """      local current      current = redis.call("incr",KEYS[1])      if tonumber(current) == 1 then        redis.call("expire",KEYS[1],ARGV[1])      end      return tonumber(redis.call("get", KEYS[1]))      """    key = self.get_md5(request)    redis_cli = get_redis_connection(self.cache)    data = redis_cli.eval(lua, 1, key, self.expire, self.limit)    return data

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到python教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 盈江县| 兰坪| 铅山县| 澄城县| 望谟县| 新源县| 陆良县| 云阳县| 普兰县| 固阳县| 郁南县| 洛南县| 阳江市| 台安县| 江永县| 临漳县| 施秉县| 中阳县| 镇远县| 鹿邑县| 车致| 乡城县| 沙雅县| 荥阳市| 达孜县| 惠水县| 江口县| 宣化县| 西林县| 重庆市| 图木舒克市| 根河市| 丘北县| 若羌县| 宝鸡市| 左权县| 开鲁县| 三原县| 宜良县| 沙洋县| 合作市|