一、视图层The view layer

Django 具有 “视图” 的概念,负责处理用户的请求并返回响应。

二、URL调度器URL dispatcher



urlpattern:URL模式

URL一般有二级:总路由和子路由

  • 主工程目录下的urls.py。url/即为总路由,myapp.urls即为子路由
urlpatterns = [path("url", view, name=None),path("url/", include(myapp.urls, namespace=xxx)),  # 包含子路由,namespace给所有的子路由起一个名字用于反向解析
]
  • 应用myapp目录下的urls.py,子路由,子路由没有include
urlpatterns = [path("url", view, name=None),  # 子路由没有include
]
  • include()的namespace和path()的name都是在反向解析中使用,即反向获取url路径:namespace.name

三、Django 如何处理一个请求?

当一个用户请求 Django 站点的一个页面,下面是 Django 系统决定执行哪个 Python 代码使用的算法:

  1. Django加载URLconf模块。如果没有传入HttpRequest 对象,Django使用根URLconf模块,即默认显示一个小火箭。否则进入以下第2步。
  2. Django加载Python代码,URLconf寻找可用的urlpatterns 。urlpatterns是django.urls.path() 和(或) django.urls.re_path() 实例的序列(sequence)。
  3. Django按顺序遍历每个urlpatterns,然后在所请求的URL匹配到第一个模式后停止,并与path_info 匹配。
  4. 一旦有URL匹配成功,Djagno导入并调用相关的视图。视图会获得如下参数:

4.1 一个 HttpRequest 实例。
4.2 如果匹配的URL包含未命名组,则使用正则表达式的匹配项作为位置参数。
4.3 关键字参数由路径表达式匹配的任何命名部分组成,并由django.urls.path() 或django.urls.re_path() 的可选 kwargs参数中指定的任何参数覆盖。

  1. 如果没有URL被匹配,或者匹配过程中出现了异常,Django调用一个适当的错误处理视图

四、URLconf在查找什么?

请求的URL被看做是一个普通的Python 字符串, URLconf在其上查找并匹配。进行匹配时将不包括GET或POST请求方式的参数以及域名。

例如, https://www.example.com/myapp/ 请求中,URLconf 将查找 myapp/
在 https://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找 myapp/ 。

**URLconf 不检查使用了哪种请求方法。**换句话讲,所有的请求方法 —— 即,对同一个URL的无论是 POST请求 、 GET请求 、或 HEAD 请求方法等等 —— 都将路由到相同的函数

五、第一种方式:path()元组

urlpatterns = [
path(‘admin/’, admin.site.urls),
path(“index/”, views.index),
path(“login/”, views.myview.as_view())]

path(route, view, kwargs=None, name=None, Pattern=None)

每个path是一个元组,path() 有五个参数,两个必须参数:route 和 view,三个可选参数:kwargs、name、pattern

path() 参数: route
route 是字符串,是匹配 URL的准则(类似正则表达式)。当 Django 响应一个request请求时,它会从 urlpatterns 的第一项开始,按顺序依次匹配用户在浏览器requested URL与列表中的每一项,直到找到匹配的项

这些准则不会匹配 GET 和 POST 参数或域名。例如,URLconf 在处理请求 https://www.example.com/myapp/ 时,它会尝试匹配 myapp/ 。处理请求 https://www.example.com/myapp/?page=3 时,也只会尝试匹配 myapp/

path() 参数: view
当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个 HttpRequest 对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。

route,处理用户的request请求对象;
view,处理服务器的response响应对象

path() 参数: kwargs
任意个关键字参数可以作为一个字典传递给目标视图函数。

path() 参数: name
为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式。

六、第二种方式:路径转换器Path converters

path - 匹配非空字符串,包括路径分隔符 ‘/’ 。它允许你匹配完整的 URL 路径而不是像 str 那样匹配 URL 的一部分。

下面的路径转换器在默认情况下是有效的:

str - 匹配除 ‘/’ 之外的非空字符串。如果表达式内不包含转换器,则会默认匹配字符串
int - 匹配 0 或任何正整数。返回一个 int 。
slug - 匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签字符串。比如,building-your-1st-django-site 。
uuid - 匹配一个格式化的 UUID 。为了防止多个 URL 映射到同一个页面,必须包含破折号并且字符都为小写。比如,075194d3-6885-417e-a8a8-6c931e272f00。返回一个 UUID 实例。

path(route, view, kwargs=None, name=None, Pattern=None)

1. 要从 URL 中取值,使用尖括号
2. 捕获的值可以选择性地包含转换器类型。比如,使用 int:name 来捕获整型参数。如果不包含转换器,则会匹配除了 / 外的任何字符。
3. route最左边不需要添加反斜杠,因为每个 URL 都有。比如,应该是 articles 而不是 /articles 。
4. route带参数,浏览器url就可以动态变化,而不是死的
5. route带参数,view也要带参数,并且参数要相同

一些请求的例子:

from django.urls import path
from . import viewsurlpatterns = [path('articles/2003/', views.special_case_2003),path('articles/<int:year>/', views.year_archive),path('articles/<int:year>/<int:month>/', views.month_archive),path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]

1.url/articles/2005/03/会匹配 URL 列表中的第三项。Django 会调用函数 views.month_archive(request, year=2005, month=3) 。
2. url/articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配, 这里 Django调用函数views.special_case_2003(request)
3. url/articles/2003 不匹配任何一个模式,因为每个模式要求 URL 以一个斜线结尾。
4. url/articles/2003/03/building-a-django-site/ 会匹配 URL 列表中的最后一项。Django 会调用函数 views.article_detail(request, year=2003, month=3, slug=“building-a-django-site”) 。

case1,path(‘articles/2003/’, views.special_case_2003)

from django.urls import path
from mysite import viewsurlpatterns = [path("articles/2021/", views.special_case_2021)
]
from django.http import HttpResponsedef special_case_2021(request):return HttpResponse("这是special_case_2021")


因为这个url是写死的,因此2021改成其它内容,会匹配失败

case2,path(‘articles/<int:year>/’, views.year_archive)

from django.urls import path
from mysite import viewsurlpatterns = [path("articles/2021/", views.special_case_2021),path("articles/<int:yyyy>/", views.year_archive)
]
from django.http import HttpResponsedef year_archive(request, yyyy):return HttpResponse("这是year_archive:{}".format(yyyy))

urls.py里的参数名yyyy要和views.py里的参数名yyyy保持一致,否则报错。


因为<int:year>,所以传入非整数类型的内容,仍然不会匹配成功

case3,path(‘articles/<int:year>/<int:month>/’, views.month_archive)

urlpatterns = [path("articles/2021/", views.special_case_2021),path("articles/<int:yyyy>/", views.year_archive),path("articles/<int:yyyy>/<int:month>/", views.month_archive)
]
from django.http import HttpResponsedef month_archive(request, yyyy, month):return HttpResponse("这是{}年{}月的archive".format(yyyy, month))


case4,path(‘articles/<int:year>/<int:month>/<slug:slug>/’, views.article_detail)

slug - 匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签字符串。比如,building-your-1st-django-site 。

from django.urls import path
from mysite import viewsurlpatterns = [# path('admin/', admin.site.urls),path("articles/2021/", views.special_case_2021),path("articles/<int:yyyy>/", views.year_archive),path("articles/<int:yyyy>/<int:month>/", views.month_archive),path("articles/<int:yyyy>/<int:mm>/<slug:slug>/", views.article_detail)
]

注:注意urlpatterns是列表,元素path()是元组,元素之间有逗号

from django.http import HttpResponsedef article_detail(request, yyyy, mm, slug):return HttpResponse("这是{}年{}月的{}".format(yyyy, mm, slug))

七、第三种方式:正则表达式regular expressions

如果path()路径和转换器语法不能很好的定义你的 URL 模式,你可以可以使用正则表达式 re_path() 。

1、在 Python 正则表达式中,命名的正则表达式组的语法是 (?P<name>pattern) ,匹配pattern并捕获结果,设置name为组名,其中 **name 是组名,pattern 是要匹配的模式**。

1、第一步要导入from django.urls import re_path
2、命名的正则表达式组的写法(?P<name>pattern),P要大写,否则报错
3、urls.py和views.py的参数name组名要保持一致,否则报错

  • 参数嵌套之后,形成内部参数、外部参数之分
  • '^comments/(?:page-(?P<page_number>\d+)/)?$',则外面的(?:page-内部参数/)为外部参数,里面的(?P<page_number>\d+)为内部参数
  • 参数,有捕获参数、非捕获参数之分
  • (?:pattern)或(pattern),匹配pattern但不捕获匹配结果。
  • (?P<name> pattern) ,匹配pattern并捕获匹配结果,设置name为组名

2、在 Python 正则表达式中,未命名的正则表达式组
例如(?P<year>[0-9]{4}) ,或使用更短的未命名组,例如([0-9]{4})

与命名的正则表达式组的区别是没有name。
当混杂命名正则和未命名正则两种样式时,任何未命名的组都会被忽略,而且只有命名的组才会传递给视图函数。

  • 不是特别推荐未命名的正则,因为它会更容易在匹配的预期含义和视图参数之间引发错误。
  • 在任何情况下,推荐在给定的正则表达式里只使用一个样式。当混杂命名正则和未命名正则两种样式时,任何未命名的组都会被忽略,而且只有命名的组才会传递给视图函数。
from django.urls import path, re_path
from mysite import viewsurlpatterns = [path("articles/2021/", views.special_case_2021),re_path(r"^articles/(?P<year>[0-9]{4})/$", views.year_archive),re_path(r"^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$", views.month_archive),re_path(r"^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$",views.article_detail)
]# urlpatterns = [
#     # path('admin/', admin.site.urls),
#     path("articles/2021/", views.special_case_2021),
#     path("articles/<int:year>/", views.year_archive),
#     path("articles/<int:year>/<int:month>/", views.month_archive),
#     path("articles/<int:year>/<int:month>/<slug:slug>/", views.article_detail)
# ]
from django.http import HttpResponsedef article_detail(request, year, month, slug):return HttpResponse("这是{}年{}月的{}".format(year, month, slug))def month_archive(request, year, month):return HttpResponse("这是{}年{}月的archive".format(year, month))def year_archive(request, year):return HttpResponse("这是year_archive:{}".format(year))def special_case_2021(request):return HttpResponse("这是special_case_2021")


这实现了与前面示例大致相同的功能,除了:

  • 将要匹配的 URLs 将稍受限制。比如,10000 年将不在匹配,因为 year 被限制长度为4。
  • 无论正则表达式进行哪种匹配,每个捕获的参数都作为字符串发送到视图
  • 当从使用 path() 切换到 re_path() (反之亦然),要特别注意,视图参数类型可能发生变化,你可能需要调整你的视图。

source:Django

Django视图层:URL调度器、Django处理一个请求、URLconf在查找什么?URL:①path()路径、②路径转换器Path converter、③正则表达式组re_path()相关推荐

  1. django 1.8 官方文档翻译: 3-1-1 URL调度器

    URL调度器 简洁.优雅的URL 模式在高质量的Web 应用中是一个非常重要的细节.Django 允许你任意设计你的URL,不受框架束缚. 不要求有.php 或.cgi,更不会要求类似0,2097,1 ...

  2. Django视图层:URL的反向解析(主路由include之namespace,子路由之name,模板标签{%url%},视图reverse()函数,反向解析示例,URL命名空间

    一.视图层The view layer Django 具有 "视图" 的概念,负责处理用户的请求并返回响应. 二.URL反向解析Reverse resolution of URLs ...

  3. Django视图层:Django便捷函数,render()函数返回HttpResponse对象,redirect()函数返回HttpResponseRedirect指向传递参数的URL

    一.视图层The view layer Django 具有 "视图" 的概念,负责处理用户的请求并返回响应. 二.render()函数 语法:render(request, tem ...

  4. Django视图层:嵌套参数,URLconf在查找什么?指定视图参数的默认值、include()路由转发三种方式、传递额外选项给 include()、传递额外选项给视图

    一.视图层The view layer Django 具有 "视图" 的概念,负责处理用户的请求并返回响应. 二.嵌套参数Nested arguments 正则表达式允许嵌套参数, ...

  5. Django视图层:视图函数、视图类

    一.视图层The view layer Django 具有 "视图" 的概念,负责处理用户的请求并返回响应. 二.视图函数 View functions mysite/views. ...

  6. 3 Django视图层

    视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...

  7. Web开发-Django视图层

    Django视图层 简述 Django框架处理业务的逻辑一般如下(省略图,源于网络,侵删) 可以看到,用户在输入网站的url之后看到的最直接的页面就是视图,而视图是基于HTML模板文件进行渲染的,数据 ...

  8. Django 视图层

    一.虚拟环境 PyCharm可以使用virtualenv中的功能来创建虚拟环境.PyCharm紧密集成了virtualenv,所以只需要在setting中配置即可创建虚拟环境.而且PyCharm捆绑了 ...

  9. Django 文档 -- 记录我的Django学习之旅

    我的学习之旅 执行查询:https://docs.djangoproject.com/zh-hans/3.1/topics/db/queries/ 执行原生 SQL 查询:https://docs.d ...

最新文章

  1. antd Form.Item 中如何获取到Select的label值
  2. 将不确定变为确定~整形变量是否可以进行位运算(像枚举类型一样)
  3. java IO(输入输出) 对象的序列化和反序列化
  4. 工厂模式——JavaScript
  5. mysql 删除外键
  6. J storm战队成员_DOTA2J.Storm战队介绍-DOTA2ESL孟买站预选赛J.Storm战队介绍_牛游戏网攻略...
  7. 2021编程语言排行:C#飙升,Python蝉联榜首
  8. 中科大计算机考研科学岛,科学岛研究生_请问谁知道研究生去合肥科学岛与在学校的利与弊啊着急!!!!_淘题吧...
  9. 轻量级服务器与云服务器的区别
  10. Scratch互动编程手柄兼容mblock网易卡搭慧编程猫Mind+ 编程键盘手柄20210223
  11. labwindows 多线程
  12. 四川安湖科技:抖音中视频的方案是什么
  13. qq(q音乐)扫码授权登陆分析及python实现
  14. 测序深度的计算,你真的掌握了吗
  15. [转]免费接口API
  16. oracle awr 执行计划,AWR(五)-利用AWR生成SQL执行计划(SQLREPORT)并进行优化 | 信春哥,系统稳,闭眼上线不回滚!...
  17. java找不到或无法加载主类
  18. 那些年,我一个人走过的坑——拆装硬盘、装内存条、装双系统
  19. M - Bombs CodeForces - 350C(方格,模拟)
  20. 为什么要限制兑换外汇额度?

热门文章

  1. 采用DCT进行图像压缩
  2. Python3基础3——List列表的增删改和内建函数的用法
  3. 思维 || Make It Equal
  4. 事件冒泡与事件捕获,附实例
  5. 《DSP using MATLAB》示例Example4.6
  6. (2015秋) 软工作业成绩公布
  7. PHP中获取文件扩展名的N种方法
  8. 解决MySQL下把结果导出到文件权限不足问题
  9. 班图ubuntu linux 5.1相当好用,windows危险了!
  10. 计算机设置成一个网络,同一个路由器上的电脑怎么设置成局域网连网打 – 手机爱问...