电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

Django url 路由匹配過程詳解

瀏覽:191日期:2024-09-13 18:35:43
1 Django 如何處理一個(gè)請(qǐng)求

當(dāng)一個(gè)用戶請(qǐng)求Django 站點(diǎn)的一個(gè)頁面,下面是Django 系統(tǒng)決定執(zhí)行哪個(gè)Python 代碼使用的算法:

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

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() 實(shí)例的序列(sequence)。其實(shí)就是我們寫的 url.py

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

一旦有 URL 匹配成功,Django 導(dǎo)入并調(diào)用相關(guān)的視圖,這個(gè)視圖是一個(gè)Python 函數(shù)(或基于類的視圖 class-based view )。匹配成功會(huì)返回一個(gè)ResolverMatch對(duì)象。

如果沒有 URL 被匹配,或者匹配過程中出現(xiàn)了異常,Django 會(huì)調(diào)用一個(gè)適當(dāng)?shù)腻e(cuò)誤處理視圖。

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

2 URL 配置文件

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

path: 用于普通路徑 re_path:用于正則路徑 include: 將一個(gè)子 url 配置文件導(dǎo)入

如下示例:

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

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

2.1 path、re_path

設(shè)置路由的幾個(gè)函數(shù)均定義在 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,這兩個(gè)函數(shù)分別被 functools 下面的 partial 封裝了一下。partial 的作用簡(jiǎn)單來說就是將一個(gè)函數(shù)的某些參數(shù)給固定住,返回一個(gè)新的函數(shù)。詳細(xì)文檔可以查看partial 文檔。這樣就不難理解 path 和 re_path,他們就是就是綁定了不同的 Pattern 參數(shù)的 _path 函數(shù)。進(jìn)一步查看 _path 內(nèi)部的邏輯,

第一個(gè)分支 如果綁定的是一個(gè) list或者tuple,使用 URLResolver 去解析,其實(shí)此時(shí)就是使用了 include 來定義 urlpattern。另外一種情況如果綁定的 view 是可以調(diào)用的,那就使用 URLPattern 去解析。URLPattern 中的 pattern 參數(shù)就是根據(jù)是采用 path/re_path 方法分別對(duì)應(yīng) 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 模塊導(dǎo)入。返回一個(gè)由子 urlconf 模塊、app_name、命名空間 namespace 組成的元組?;氐絼倓偵厦娴?_path 中第一個(gè)分支。將這個(gè)元組里面參數(shù)代入 URLResolver 并返回。

3 URLPattern 與 URLResolver3.1 URLPattern

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

class URLPattern: def __init__(self, pattern, callback, default_args=None, name=None): # 需要匹配的 urlpattern,這里根據(jù)是path還是re_path 分別是 RoutePattern或RegexPattern的實(shí)例 self.pattern = pattern self.callback = callback # the view self.default_args = default_args or {} self.name = name ... def resolve(self, path): 調(diào)用 RoutePattern 或 RegexPattern 的實(shí)例中的 match 方法進(jìn)行匹配(注意這里不是 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 初始化時(shí)其中的 pattern 就是根據(jù)是使用 path/re_path 分別對(duì)應(yīng)RoutePattern或RegexPattern。其實(shí)就是指定匹配的模式是普通路由還是正則的路由。

3.2 URLResolver

URLResolver 源碼中比較核心的是 resolve 函數(shù),就是傳入一個(gè) path,進(jìn)行匹配。

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 # 如果匹配成功,則繼續(xù)匹配它的url_patterns for pattern in self.url_patterns:try: # 這個(gè)pattern可能是URLPattern,也可能是URLResolver;如果是URLPattern,匹配成功則返回ResolverMatch;如果是URLResolver,則會(huì)遞歸調(diào)用下去。 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 比較關(guān)鍵的邏輯在 循環(huán)匹配 pattern 過程,如果 pattern是URLPattern匹配成功直接返回ResolverMatch,如果是另一個(gè)URLResolver,則實(shí)現(xiàn)了遞歸調(diào)用。

Django url 路由匹配過程詳解

Django 就是通過這個(gè) URLResolver 實(shí)現(xiàn)了多級(jí) URL 配置。

4 總結(jié)

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

本文從全局的角度大致說明了Django路由的匹配流程,后續(xù)將從細(xì)節(jié)部分說明其中的一些關(guān)鍵點(diǎn)。

到此這篇關(guān)于Django url 路由匹配過程詳解的文章就介紹到這了,更多相關(guān)Django url 路由匹配內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Django
相關(guān)文章:
主站蜘蛛池模板: 大白菜官网,大白菜winpe,大白菜U盘装系统, u盘启动盘制作工具 | 柔性输送线|柔性链板|齿形链-上海赫勒输送设备有限公司首页[输送机] | 网络推广公司_网络营销方案策划_企业网络推广外包平台-上海澜推网络 | 上海小程序开发-上海小程序制作公司-上海网站建设-公众号开发运营-软件外包公司-咏熠科技 | CE认证_FCC认证_CCC认证_MFI认证_UN38.3认证-微测检测 CNAS实验室 | 鹤壁创新仪器公司-全自动量热仪,定硫仪,煤炭测硫仪,灰熔点测定仪,快速自动测氢仪,工业分析仪,煤质化验仪器 | 27PR跨境电商导航 | 专注外贸跨境电商 | 胶水,胶粘剂,AB胶,环氧胶,UV胶水,高温胶,快干胶,密封胶,结构胶,电子胶,厌氧胶,高温胶水,电子胶水-东莞聚力-聚厉胶粘 | 塑胶跑道_学校塑胶跑道_塑胶球场_运动场材料厂家_中国塑胶跑道十大生产厂家_混合型塑胶跑道_透气型塑胶跑道-广东绿晨体育设施有限公司 | 耳模扫描仪-定制耳机设计软件-DLP打印机-asiga打印机-fitshape「飞特西普」 | 重庆私家花园设计-别墅花园-庭院-景观设计-重庆彩木园林建设有限公司 | 橡胶接头_橡胶软接头_可曲挠橡胶接头-巩义市创伟机械制造有限公司 | 原色会计-合肥注册公司_合肥代理记账公司_营业执照代办 | 双齿辊破碎机-大型狼牙破碎机视频-对辊破碎机价格/型号图片-金联机械设备生产厂家 | 岩棉板|岩棉复合板|聚氨酯夹芯板|岩棉夹芯板|彩钢夹芯板-江苏恒海钢结构 | 办公室家具公司_办公家具品牌厂家_森拉堡办公家具【官网】 | 聚合氯化铝厂家-聚合氯化铝铁价格-河南洁康环保科技 | 合肥活动房_安徽活动板房_集成打包箱房厂家-安徽玉强钢结构集成房屋有限公司 | 车辆定位管理系统_汽车GPS系统_车载北斗系统 - 朗致物联 | 非标压力容器_碳钢储罐_不锈钢_搪玻璃反应釜厂家-山东首丰智能环保装备有限公司 | 天津热油泵_管道泵_天津高温热油泵-天津市金丰泰机械泵业有限公司【官方网站】 | 阿尔法-MDR2000无转子硫化仪-STM566 SATRA拉力试验机-青岛阿尔法仪器有限公司 | 合肥升降机-合肥升降货梯-安徽升降平台「厂家直销」-安徽鼎升自动化科技有限公司 | 快干水泥|桥梁伸缩缝止水胶|伸缩缝装置生产厂家-广东广航交通科技有限公司 | 苏州伊诺尔拆除公司_专业酒店厂房拆除_商场学校拆除_办公楼房屋拆除_家工装拆除拆旧 | 纸张环压仪-纸张平滑度仪-杭州纸邦自动化技术有限公司 | 东莞猎头公司_深圳猎头公司_广州猎头公司-广东万诚猎头提供企业中高端人才招聘服务 | 外贮压-柜式-悬挂式-七氟丙烷-灭火器-灭火系统-药剂-价格-厂家-IG541-混合气体-贮压-非贮压-超细干粉-自动-灭火装置-气体灭火设备-探火管灭火厂家-东莞汇建消防科技有限公司 | ptc_浴霸_大巴_干衣机_呼吸机_毛巾架_电动车加热器-上海帕克 | 商秀—企业短视频代运营_抖音企业号托管 | 南京和瑞包装有限公司 | 考勤系统_考勤管理系统_网络考勤软件_政企|集团|工厂复杂考勤工时统计排班管理系统_天时考勤 | 超声骨密度仪-动脉硬化检测仪器-人体成分分析仪厂家/品牌/价格_南京科力悦 | 天津拓展_天津团建_天津趣味运动会_天津活动策划公司-天津华天拓展培训中心 | 膏剂灌装旋盖机-眼药水灌装生产线-西林瓶粉剂分装机-南通博琅机械科技 | 碎石机设备-欧版反击破-欧版颚式破碎机(站)厂家_山东奥凯诺机械 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 全自动包衣机-无菌分装隔离器-浙江迦南科技股份有限公司 | VOC检测仪-甲醛检测仪-气体报警器-气体检测仪厂家-深恒安科技有限公司 | 选宝石船-陆地水上开采「精选」色选机械设备-青州冠诚重工机械有限公司 | 合肥网带炉_安徽箱式炉_钟罩炉-合肥品炙装备科技有限公司 | 吹塑加工_大型吹塑加工_滚塑代加工-莱力奇吹塑加工有限公司 |