婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Django url 路由匹配過程詳解

Django url 路由匹配過程詳解

熱門標簽:甘肅高頻外呼系統 滴滴地圖標注公司 天津塘沽區地圖標注 地圖標注可以遠程操作嗎 如何申請400電話代理 400電話在線如何申請 江門智能電話機器人 杭州房產地圖標注 智能電話機器人調研

1 Django 如何處理一個請求

當一個用戶請求Django 站點的一個頁面,下面是Django 系統決定執行哪個Python 代碼使用的算法:

Django 確定使用根 URLconf 模塊。通常,這是 ROOT_URLCONF 設置的值(即 settings 中的 ROOT_URLCONF),但如果傳入 HttpRequest 對象擁有 urlconf 屬性(通過中間件設置),它的值將被用來代替 ROOT_URLCONF 設置。可以在 django/core/handlers/base.py 發現該邏輯。

class BaseHandler:
  ...
  def _get_response(self, request):
    ...
    if hasattr(request, 'urlconf'):
      urlconf = request.urlconf
      set_urlconf(urlconf)
      resolver = get_resolver(urlconf)
    else:
      resolver = get_resolver()

Django 加載該 Python 模塊并尋找可用的 urlpatterns 。它是 django.urls.path() 和(或) django.urls.re_path() 實例的序列(sequence)。其實就是我們寫的 url.py

Django 會按順序遍歷每個 URL 模式,然后會在所請求的URL匹配到第一個模式后停止,并與 path_info 匹配。這個是路由匹配的關鍵,相關邏輯均在django/urls/resolvers.py。其中有幾個比較重要的概念,如RegexPattern、RoutePattern、URLPattern、URLResolver。其中URLResolver有嵌套的邏輯,下文詳述。

一旦有 URL 匹配成功,Django 導入并調用相關的視圖,這個視圖是一個Python 函數(或基于類的視圖 class-based view )。匹配成功會返回一個ResolverMatch對象。

如果沒有 URL 被匹配,或者匹配過程中出現了異常,Django 會調用一個適當的錯誤處理視圖。

本文詳述 2、3,即 urlpatterns 相關概念和路由匹配的過程。

2 URL 配置文件

在 Django 2 之后通常會使用 path/re_path 來設置路由,還要一個比較特殊的方法 include 。

  • path: 用于普通路徑
  • re_path:用于正則路徑
  • include: 將一個子 url 配置文件導入

如下示例:

urlpatterns = [
  path('index/', views.index), # 普通路徑
  re_path(r'^articles/([0-9]{4})/$', views.articles), # 正則路徑
  path("app01/", include("app01.urls")),
]

上面的配置文件,設置了3條 urlpattern,分別是普通路徑 index/ 與 視圖函數 views.index,正則路徑 ^articles/([0-9]{4})/$ 與視圖函數 views.articles 綁定。app01/ 和app01.urls 綁定,app01.urls 不是一個視圖函數,而是一個子模塊的 urlpatterns。
可以看到 urlpattern 可以把一個 url 和視圖函數綁定,也可以和一個子 urlpattern 進行綁定。

2.1 path、re_path

設置路由的幾個函數均定義在 django/urls/conf.py 中。

def include(arg, namespace=None):
  ...
  return (urlconf_module, app_name, namespace)


def _path(route, view, kwargs=None, name=None, Pattern=None):
  if isinstance(view, (list, tuple)):
    # For include(...) processing.
    pattern = Pattern(route, is_endpoint=False)
    urlconf_module, app_name, namespace = view
    return URLResolver(
      pattern,
      urlconf_module,
      kwargs,
      app_name=app_name,
      namespace=namespace,
    )
  elif callable(view):
    pattern = Pattern(route, name=name, is_endpoint=True)
    return URLPattern(pattern, view, kwargs, name)
  else:
    raise TypeError('view must be a callable or a list/tuple in the case of include().')


path = partial(_path, Pattern=RoutePattern)
re_path = partial(_path, Pattern=RegexPattern)

首先先來看下 path 和 re_path,這兩個函數分別被 functools 下面的 partial 封裝了一下。partial 的作用簡單來說就是將一個函數的某些參數給固定住,返回一個新的函數。詳細文檔可以查看partial 文檔。
這樣就不難理解 path 和 re_path,他們就是就是綁定了不同的 Pattern 參數的 _path 函數。進一步查看 _path 內部的邏輯,

第一個分支 如果綁定的是一個 list或者tuple,使用 URLResolver 去解析,其實此時就是使用了 include 來定義 urlpattern。
另外一種情況如果綁定的 view 是可以調用的,那就使用 URLPattern 去解析。URLPattern 中的 pattern 參數就是根據是采用 path/re_path 方法分別對應 RoutePattern/RegexPattern。

2.2 include

def include(arg, namespace=None):
  ...
  if isinstance(urlconf_module, str):
    urlconf_module = import_module(urlconf_module)
  patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
  app_name = getattr(urlconf_module, 'app_name', app_name)
  ...
  return (urlconf_module, app_name, namespace)

include 方法所做的工作就是通過 import_module 將定義的 url 模塊導入。返回一個由子 urlconf 模塊、app_name、命名空間 namespace 組成的元組。回到剛剛上面的 _path 中第一個分支。將這個元組里面參數代入 URLResolver 并返回。

3 URLPattern 與 URLResolver

3.1 URLPattern

上面提到如果url定義中綁定是一個可以直接調用的view。那就是使用URLPattern直接去解析。

class URLPattern:
  def __init__(self, pattern, callback, default_args=None, name=None):
    # 需要匹配的 urlpattern,這里根據是path還是re_path 分別是 RoutePattern或RegexPattern的實例
    self.pattern = pattern
    self.callback = callback # the view
    self.default_args = default_args or {}
    self.name = name
  ...
  def resolve(self, path):
    調用 RoutePattern 或 RegexPattern 的實例中的 match 方法進行匹配(注意這里不是 re 模塊里面的 match)
    match = self.pattern.match(path)
    if match:
      new_path, args, kwargs = match
      # Pass any extra_kwargs as **kwargs.
      kwargs.update(self.default_args)
      # 匹配成功返回 `ResolverMatch`
      return ResolverMatch(self.callback, args, kwargs, self.pattern.name, route=str(self.pattern))
  ...

URLPattern 初始化時其中的 pattern 就是根據是使用 path/re_path 分別對應RoutePattern或RegexPattern。其實就是指定匹配的模式是普通路由還是正則的路由。

3.2 URLResolver

URLResolver 源碼中比較核心的是 resolve 函數,就是傳入一個 path,進行匹配。

class URLResolver:
  def resolve(self, path):
    path = str(path) # path may be a reverse_lazy object
    tried = []
    # 匹配 path
    match = self.pattern.match(path)
    if match:
      new_path, args, kwargs = match
      # 如果匹配成功,則繼續匹配它的url_patterns
      for pattern in self.url_patterns:
        try:
          # 這個pattern可能是URLPattern,也可能是URLResolver;如果是URLPattern,匹配成功則返回ResolverMatch;如果是URLResolver,則會遞歸調用下去。
          sub_match = pattern.resolve(new_path)
        ...
        else:
          if sub_match:
            ...
            # 匹配成功返回ResolverMatch
            return ResolverMatch(
              sub_match.func,
              sub_match_args,
              sub_match_dict,
              sub_match.url_name,
              [self.app_name] + sub_match.app_names,
              [self.namespace] + sub_match.namespaces,
              self._join_route(current_route, sub_match.route),
            )
          tried.append([pattern])
      raise Resolver404({'tried': tried, 'path': new_path})
    raise Resolver404({'path': path})

URLResolver 比較關鍵的邏輯在 循環匹配 pattern 過程,如果 pattern是URLPattern匹配成功直接返回ResolverMatch,如果是另一個URLResolver,則實現了遞歸調用。

Django 就是通過這個 URLResolver 實現了多級 URL 配置。

4 總結

Django 路由匹配的有幾個比較核心的概念 path/re_path/include、RegexPattern/RoutePattern、URLPattern/URLResolver。
首先用 partial 封裝 _path,綁定了一個 pattern 匹配模式(RegexPattern/RoutePattern),后面多次用到了這個 pattern。然后就是根據 view 是元組還是可調用視圖函數,分別使用URLResolver和URLPattern去解析,這兩個類解析之后都會返回給ResolverMatch,由它去回調匹配成功后的結果(view和args等)。

本文從全局的角度大致說明了Django路由的匹配流程,后續將從細節部分說明其中的一些關鍵點。

到此這篇關于Django url 路由匹配過程詳解的文章就介紹到這了,更多相關Django url 路由匹配內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • python基于爬蟲+django,打造個性化API接口
  • 詳解Django關于StreamingHttpResponse與FileResponse文件下載的最優方法
  • Django 實現圖片上傳和下載功能
  • Django前后端分離csrf token獲取方式
  • django中ImageField的使用詳解
  • Django用內置方法實現簡單搜索功能的方法
  • 用ldap作為django后端用戶登錄驗證的實現
  • 詳解Django自定義圖片和文件上傳路徑(upload_to)的2種方式
  • Django數據統計功能count()的使用
  • Django REST Framework 分頁(Pagination)詳解
  • 如何用Django處理gzip數據流

標簽:東莞 重慶 河池 漢中 臨汾 長春 德宏 廊坊

巨人網絡通訊聲明:本文標題《Django url 路由匹配過程詳解》,本文關鍵詞  Django,url,路由,匹配,過程,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Django url 路由匹配過程詳解》相關的同類信息!
  • 本頁收集關于Django url 路由匹配過程詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久久久久久99久久久精品网站| 日韩一区二区影院| 欧美精品乱码久久久久久| 亚洲美女视频一区| 99久久99久久久精品齐齐| 国产精品私房写真福利视频| 国产aⅴ综合色| 亚洲精品视频在线| 欧美日韩三级视频| 国产一区二区在线免费观看| 国产日产欧美一区| 91免费视频网址| 亚洲成人激情自拍| 精品国产a毛片| www.亚洲色图| 天堂蜜桃91精品| 久久精品人人做| 在线看一区二区| 久久99精品久久久久久久久久久久| 久久新电视剧免费观看| 97精品视频在线观看自产线路二| 夜夜精品浪潮av一区二区三区| 91精品国产综合久久蜜臀| 国产成+人+日韩+欧美+亚洲| 亚洲精品视频在线观看网站| 欧美videofree性高清杂交| 成av人片一区二区| 亚洲成人激情av| 久久精品一区蜜桃臀影院| 91一区二区在线观看| 久久精品国产精品亚洲精品 | 日韩一区二区三区电影 | 成人黄色综合网站| 日本视频在线一区| 亚洲色图视频网| 日韩午夜小视频| 色94色欧美sute亚洲13| 国产一区二区三区黄视频| 午夜精品久久久久影视| ●精品国产综合乱码久久久久| 精品国产伦一区二区三区观看体验 | 欧美情侣在线播放| 国产精品亚洲第一区在线暖暖韩国| 亚洲成人午夜影院| 国产精品色哟哟| 日韩精品一区二区三区四区| 色欧美乱欧美15图片| 国产99久久久国产精品潘金网站| 日韩精品免费专区| 夜夜精品浪潮av一区二区三区| 国产精品免费久久| 久久久不卡网国产精品一区| 日韩欧美色电影| 日韩精品一区二区三区swag | 久久―日本道色综合久久| 欧美日韩高清影院| 欧美日韩亚洲高清一区二区| 欧洲国内综合视频| 欧美特级限制片免费在线观看| 色婷婷综合久久久久中文| 99精品久久久久久| 色婷婷久久综合| 欧美天堂亚洲电影院在线播放| 在线一区二区三区四区| 欧美性猛交xxxxxx富婆| 欧美日韩精品一区二区| 6080日韩午夜伦伦午夜伦| 日韩一区二区免费在线观看| 日韩一区二区中文字幕| www久久久久| 中文字幕av免费专区久久| 最新欧美精品一区二区三区| 亚洲欧美福利一区二区| 亚洲国产另类av| 男女性色大片免费观看一区二区| 日本美女一区二区三区视频| 美女精品自拍一二三四| 国产乱码精品一区二区三区av| 国产精一区二区三区| www.亚洲激情.com| 欧美日韩国产系列| 欧美成人女星排名| 国产欧美精品一区二区色综合 | 99久久精品国产导航| 一本色道久久加勒比精品 | 欧美日韩国产大片| 日韩无一区二区| 欧美激情一区二区在线| 中文字幕在线一区免费| 亚洲国产aⅴ天堂久久| 激情久久五月天| 在线精品视频一区二区| 精品久久一区二区| 一区二区三区在线视频观看58| 麻豆精品在线视频| 91日韩一区二区三区| 日韩精品影音先锋| 美腿丝袜亚洲一区| 成人综合在线视频| 欧美日韩国产123区| 国产女同性恋一区二区| 午夜精品福利在线| 成人sese在线| 337p日本欧洲亚洲大胆色噜噜| 亚洲精品乱码久久久久| 国产精品一卡二| 91精品欧美久久久久久动漫| 中文子幕无线码一区tr| 久久精品噜噜噜成人88aⅴ| 91福利在线看| 国产欧美视频一区二区| 久久精品国产澳门| 欧美久久婷婷综合色| 国产精品不卡一区二区三区| 久久福利资源站| 91精品在线观看入口| 亚洲综合清纯丝袜自拍| 波多野结衣中文字幕一区| 欧美精品一区二区蜜臀亚洲| 午夜精品久久久久久久| 欧美制服丝袜第一页| 国产精品三级电影| 国产成人午夜高潮毛片| 日韩一区二区免费视频| 偷拍与自拍一区| 欧美午夜一区二区| 成人免费在线视频| 99热99精品| 最好看的中文字幕久久| 91在线高清观看| 亚洲欧美乱综合| 欧美性猛片aaaaaaa做受| 亚洲一区在线观看网站| 欧美色网站导航| 亚洲精品久久7777| 在线观看欧美黄色| 亚洲小说春色综合另类电影| 在线观看免费亚洲| 午夜视频在线观看一区二区 | 亚洲蜜臀av乱码久久精品| 97久久精品人人澡人人爽| 亚洲日本电影在线| 91黄色小视频| 午夜精品久久久久久久久久久| 6080国产精品一区二区| 麻豆精品视频在线观看免费| 久久亚洲一区二区三区四区| 国产99久久久国产精品免费看 | 视频一区二区中文字幕| 91麻豆精品国产91久久久久久久久| 日韩高清在线一区| 欧美精品一区二区精品网| 国产精品一区二区在线观看网站| 久久亚洲一区二区三区明星换脸| 国产成人啪免费观看软件| 中文字幕中文字幕中文字幕亚洲无线| 99久久精品情趣| 图片区小说区国产精品视频| 精品国产乱码久久久久久浪潮| 国产成人一级电影| 国产日韩精品一区二区三区 | 婷婷综合另类小说色区| 日韩色视频在线观看| 精品福利在线导航| 国产高清久久久久| 亚洲精品高清在线| 精品女同一区二区| 在线视频欧美精品| 久久99精品久久久久久动态图 | 亚洲视频免费在线| 欧美亚洲禁片免费| 国产麻豆日韩欧美久久| 亚洲国产精品嫩草影院| 久久精品亚洲国产奇米99| 精品视频在线免费看| 粉嫩aⅴ一区二区三区四区五区| 亚洲第一综合色| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 国产成都精品91一区二区三| 亚洲欧美电影一区二区| 欧美v国产在线一区二区三区| 99久久精品免费观看| 欧美a级理论片| 一区二区在线观看不卡| 久久蜜桃av一区精品变态类天堂| 91久久线看在观草草青青| 精品制服美女久久| 午夜精品久久久久| 亚洲精品一二三四区| 国产无一区二区| 精品精品欲导航| 欧美美女一区二区在线观看| 99久久精品免费| 成人在线综合网站| 蜜臀av一区二区| 天堂在线亚洲视频| 亚洲第一激情av| 亚洲香肠在线观看| 一区二区三区欧美久久| 一区二区三区**美女毛片|