最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django中間件工作流程及寫法實(shí)例代碼

 更新時(shí)間:2018年02月06日 10:34:56   作者:扎心了老鐵  
這篇文章主要介紹了Django中間件工作流程及寫法實(shí)例代碼,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下

熟悉web開發(fā)的同學(xué)對(duì)hook鉤子肯定不陌生,通過(guò)鉤子可以方便的實(shí)現(xiàn)一些觸發(fā)和回調(diào),并且做一些過(guò)濾和攔截。

django中的中間件(middleware)就是類似鉤子的一種存在。下面我們來(lái)介紹一下,并且給出一些實(shí)例。

1、Middleware的工作流程

我盜了一個(gè)圖,看網(wǎng)上很多人用這個(gè)圖,來(lái)源已經(jīng)追不明白了。簡(jiǎn)單聲明一下,這個(gè)圖不是我的??粗鴪D我們分析一下:

1)django的請(qǐng)求相應(yīng)流程:HttpRequest -> RequestMiddleware -> view function -> ResponseMiddleware -> HttpResponse

可以看到一個(gè)請(qǐng)求到響應(yīng)的過(guò)程,中間夾著兩個(gè)middleware流程,請(qǐng)求中間件和響應(yīng)中間件。

也就是說(shuō),django提供了一種機(jī)制,在:

  1. 請(qǐng)求到達(dá)視圖函數(shù)中間
  2. 視圖函數(shù)到響應(yīng)之間

支持嵌入鉤子。

這種鉤子的特點(diǎn):

  1. 全局,一旦你使用了中間件,并且發(fā)布生效的話,所有的請(qǐng)求都會(huì)經(jīng)過(guò)你嵌入的中間件。
  2. 性能敏感,如果你的中間件性能差的話,那么會(huì)影響服務(wù)的整體性能。

2) django的middleware包含四個(gè)鉤子函數(shù):process_request/process_view/process_response/process_exception

process_request:接受request之后確定所執(zhí)行的view之前

process_view:確定了所要執(zhí)行的view之后,view真正執(zhí)行之前

process_response:view執(zhí)行之后

process_exceptionview:view執(zhí)行拋出異常

而插入middleware的過(guò)程是在settings.py中配置,如下默認(rèn)配置,我只截取了兩個(gè)中間件:SessionMiddleware和CommonMiddleware。

MIDDLEWARE_CLASSES = (
  'django.contrib.sessions.middleware.SessionMiddleware',
  'django.middleware.common.CommonMiddleware',
  
  ...    
)

我們簡(jiǎn)單看一下SessionMiddleware的實(shí)現(xiàn)

import time
from importlib import import_module

from django.conf import settings
from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date


class SessionMiddleware(object):
  def __init__(self):
    engine = import_module(settings.SESSION_ENGINE)
    self.SessionStore = engine.SessionStore

  def process_request(self, request):
    session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
    request.session = self.SessionStore(session_key)

  def process_response(self, request, response):
    """
    If request.session was modified, or if the configuration is to save the
    session every time, save the changes and set a session cookie or delete
    the session cookie if the session has been emptied.
    """
    try:
      accessed = request.session.accessed
      modified = request.session.modified
      empty = request.session.is_empty()
    except AttributeError:
      pass
    else:
      # First check if we need to delete this cookie.
      # The session should be deleted only if the session is entirely empty
      if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
        response.delete_cookie(settings.SESSION_COOKIE_NAME)
      else:
        if accessed:
          patch_vary_headers(response, ('Cookie',))
        if modified or settings.SESSION_SAVE_EVERY_REQUEST:
          if request.session.get_expire_at_browser_close():
            max_age = None
            expires = None
          else:
            max_age = request.session.get_expiry_age()
            expires_time = time.time() + max_age
            expires = cookie_date(expires_time)
          # Save the session data and refresh the client cookie.
          # Skip session save for 500 responses, refs #3881.
          if response.status_code != 500:
            request.session.save()
            response.set_cookie(settings.SESSION_COOKIE_NAME,
                request.session.session_key, max_age=max_age,
                expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
                path=settings.SESSION_COOKIE_PATH,
                secure=settings.SESSION_COOKIE_SECURE or None,
                httponly=settings.SESSION_COOKIE_HTTPONLY or None)
    return response

可以看到在SessionMiddleware中默認(rèn)只實(shí)現(xiàn)了process_requestprocess_response兩個(gè)hook函數(shù)。

我們就以這個(gè)例子說(shuō)明一下一個(gè)請(qǐng)求的執(zhí)行過(guò)程。我們假設(shè)場(chǎng)景是這樣的:

1)從上而下配置了兩個(gè)Middleware(注意順序):SessionMiddleware和CommonMiddleware

2)每個(gè)Middleware中的四個(gè)鉤子函數(shù)齊全process_request/process_view/process_response/process_exception

執(zhí)行順序應(yīng)該是這樣的:

1、HttpRequest

2、SessionMiddleware process_request

3、SessionMiddleware process_view

4、CommonMiddleware process_request

5、CommonMiddleware process_view

6、view

7、CommonMiddleware process_response

8、CommonMiddleware process_exception(如有必要)

9、SessionMiddleware process_response

10、SessionMiddleware process_exception(如有必要)

11、HttpResponse

2、Middleware的寫法

Middleware的寫法很簡(jiǎn)單:

1)實(shí)現(xiàn)一個(gè)類,繼承object就行;

2)重寫其中的四個(gè)鉤子函數(shù)就可以了。

這里要著重說(shuō)一個(gè)常用的功能。

攔截器/過(guò)濾器(filter)

一般來(lái)說(shuō),每一個(gè)請(qǐng)求都要經(jīng)過(guò)process_request這個(gè)鉤子函數(shù)。你的實(shí)現(xiàn)中,函數(shù)的執(zhí)行結(jié)果必然有兩種(你要自己做異常處理):

1)None

2)HttpResponse 對(duì)象

如果返回None,請(qǐng)求流程繼續(xù)執(zhí)行,也就是繼續(xù)進(jìn)入其他的Middleware或者鉤子函數(shù)。

如果返回HttpResponse對(duì)象,那么就直接返回到頁(yè)面。通過(guò)這個(gè)功能我們可以做黑名單。

給一個(gè)例子:

就是統(tǒng)計(jì)pv

# -*- coding:utf-8 -*-
from datetime import datetime
from data_monitor.utils.dbmanager import MysqlManager
from data_monitor.common.constant import MYSQL_JOBS as mysql_config

class RequestHookMiddleware(object):

  def process_request(self, request):
    try:
      username = request.COOKIES.get('username')
      uri = request.path
      timestamp = str(datetime.now())
      db_obj = MysqlManager(
        mysql_config.get('host'),
        mysql_config.get('port'),
        mysql_config.get('db'),
        mysql_config.get('user'),
        mysql_config.get('password'),
        format=True,
      )
      field_str = 'username, uri, timestamp'
      value_str = '"%s","%s","%s"' % (username, uri, timestamp)
      db_obj.insert('pv', field_str, value_str)
      db_obj.close()
      return
    except Exception, ex:
      return

總結(jié)

以上就是本文關(guān)于Django中間件工作流程及寫法實(shí)例代碼的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • Python中Jupyter notebook快捷鍵總結(jié)

    Python中Jupyter notebook快捷鍵總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于Python中Jupyter notebook快捷鍵總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-04-04
  • python設(shè)置中文界面實(shí)例方法

    python設(shè)置中文界面實(shí)例方法

    在本篇文章里小編給大家整理的是關(guān)于python設(shè)置中文界面實(shí)例方法,有興趣的朋友們可以學(xué)習(xí)參考下。
    2020-10-10
  • Python?torch.fft.rfft()函數(shù)用法示例代碼

    Python?torch.fft.rfft()函數(shù)用法示例代碼

    大家應(yīng)該都知道新舊版的torch中的傅里葉變換函數(shù)在定義和用法上有所不同,下面這篇文章主要給大家介紹了關(guān)于Python?torch.fft.rfft()函數(shù)用法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • python在Windows8下獲取本機(jī)ip地址的方法

    python在Windows8下獲取本機(jī)ip地址的方法

    這篇文章主要介紹了python在Windows8下獲取本機(jī)ip地址的方法,涉及Python中socket包相關(guān)函數(shù)的使用技巧,需要的朋友可以參考下
    2015-03-03
  • Python使用Pandas讀寫Excel實(shí)例解析

    Python使用Pandas讀寫Excel實(shí)例解析

    這篇文章主要介紹了Python使用Pandas讀寫Excel實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 3種適用于Python的瘋狂秘密武器及原因解析

    3種適用于Python的瘋狂秘密武器及原因解析

    這篇文章主要介紹了3種適用于Python的瘋狂秘密武器,本文給大家分享問(wèn)題原因解析,通過(guò)實(shí)例代碼圖文的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 獨(dú)立進(jìn)程使用django模型及django.setup()使用

    獨(dú)立進(jìn)程使用django模型及django.setup()使用

    這篇文章主要介紹了獨(dú)立進(jìn)程使用django模型(django.setup()使用),它提供了一種簡(jiǎn)單且高效的方式來(lái)利用Django強(qiáng)大的功能,并使你的代碼更易于維護(hù)和擴(kuò)展,需要的朋友可以參考下
    2023-07-07
  • 在Python中定義函數(shù)并調(diào)用的操作步驟

    在Python中定義函數(shù)并調(diào)用的操作步驟

    這篇文章主要介紹了在Python中如何定義函數(shù)并調(diào)用它,函數(shù)的定義和調(diào)用是Python編程中最基本也是最重要的概念之一,掌握它們對(duì)于進(jìn)行有效的Python編程至關(guān)重要,需要的朋友可以參考下
    2024-01-01
  • Python json解析庫(kù)jsonpath原理及使用示例

    Python json解析庫(kù)jsonpath原理及使用示例

    這篇文章主要介紹了Python json解析庫(kù)jsonpath原理及使用示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • python 實(shí)現(xiàn)在txt指定行追加文本的方法

    python 實(shí)現(xiàn)在txt指定行追加文本的方法

    下面小編就為大家分享一篇python 實(shí)現(xiàn)在txt指定行追加文本的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04

最新評(píng)論

沙雅县| 剑河县| 呼图壁县| 道孚县| 鄂伦春自治旗| 茂名市| 丰县| 巫山县| 泾阳县| 山阴县| 黑龙江省| 罗田县| 将乐县| 安康市| 吕梁市| 东辽县| 永和县| 那曲县| 六盘水市| 平陆县| 广安市| 自治县| 潼南县| 蒲城县| 通海县| 利津县| 北流市| 彰武县| 洪泽县| 岫岩| 南部县| 蓝山县| 白沙| 滨州市| 临漳县| 许昌市| 鸡泽县| 吉安县| 黑水县| 阳原县| 嵊泗县|