在一个请求到达的时候,最先达到的就是视图层,然后根据url映射到视图函数。这一部分我们来说明url的配置。

概述

为了给一个应用设计URL,你需要创建一个Python 模块,通常称为URLconf(URL configuration)。 这个模块是纯粹的Python 代码,包含URL 模式(简单的正则表达式)到Python 函数(你的视图)的简单映射。

映射可短可长,随便你。 它可以引用其它的映射。 而且,因为它是纯粹的Python 代码,它可以动态构造。

django如何处理请求

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

  1. Django 决定要使用的根URLconf 模块。 通常,这是ROOT_URLCONF设置的值,但是如果传入的HttpRequest对象具有urlconf属性(由中间件设置),则其值将被用于代替ROOT_URLCONF设置。
  2. Django 加载该Python 模块并寻找可用的urlpatterns。 它是django.conf.urls.url() 实例的一个Python 列表。
  3. Django 依次匹配每个URL 模式,在与请求的URL 匹配的第一个模式停下来。
  4. 一旦正则表达式匹配,Django将导入并调用给定的视图,该视图是一个简单的Python函数(或基于类的class-based view)。 视图将获得如下参数:
    • 一个HttpRequest 实例。
    • 如果匹配的正则表达式返回了没有命名的组,那么正则表达式匹配的内容将作为位置参数提供给视图。
    • 关键字参数由正则表达式匹配的命名组组成,但是可以被django.conf.urls.url()的可选参数kwargs覆盖。
  5. 如果没有匹配到正则表达式,或者如果过程中抛出一个异常,Django 将调用一个适当的错误处理视图。

在官网上有一个实例和说明,来说明url是怎么匹配的,如下:

from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
] #需要注意的是:
若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。 #参照请求实例的第一个和最后一个。
不需要添加一个前导的反斜杠,因为每个URL 都有。 例如,应该是^articles 而不是 ^/articles。
每个正则表达式前面的'r' 是可选的但是建议加上。 它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义。 #一些请求实例 /articles/2005/03/ 请求将匹配列表中的第三个模式。 Django 将调用函数views.month_archive(request, '2005', '03')。
/articles/2005/3/ 不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
/articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。 请像这样自由插入一些特殊的情况来探测匹配的次序。 这里,Django会调用函数views.special_case_2003(request)
/articles/2003 不匹配任何一个模式,因为每个模式要求URL 以一个斜线结尾。
/articles/2003/03/03/ 将匹配最后一个模式。 Django 将调用函数views.article_detail(request, '2003', '03', '03')。

命名组

上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图。 在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。

在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中name 是组的名称,pattern 是要匹配的模式。

from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。 像这样:


  • /articles/2005/03/ 请求将调用views.month_archive(request, year='2005', month='03')函数,而不是views.month_archive(request, '2005', '03')
  • /articles/2003/03/03/ 请求将调用函数views.article_detail(request, year='2003', month='03',day='03')

需要注意的是,无论捕获的参数是什么类型,总是作为字符串传递给视图函数。譬如上面捕获了年份为整型,但是仍然是作为字符串传递的。

匹配/分组算法

下面是URLconf 解析器使用的算法,针对正则表达式中的命名组和非命名组:

  1. 如果有命名参数,则使用这些命名参数,忽略非命名参数。
  2. 否则,它将以位置参数传递所有的非命名参数。

URLconf的查找

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

例如,在https://www.example.com/myapp/的请求中,URLconf将查找myapp/

https://www.example.com/myapp/?page=3的请求中,URLconf将查找myapp/

URLconf 不检查使用了哪种请求方法。 换句话说,所有请求方法 - POSTGETHEAD等 - 将路由到同一个URL的相同功能。

通过一个实例,来说明上面的参数传递:

url映射如下:
url(r'^sign/([0-9]{4})/([0-9]{2})/$', sign), #传递位置参数
url(r'^sign/(?P<year>[0-9]{4})/(?P<mon>[0-9]{2})/(?P<day>[0-9]{2})/$', sign), #传递关键字参数 #视图函数如下:
def sign(request, year, mon, day="02"): #需要形参来接收url传递过滤的实参
return render(request, "sign.html", {"year": year, "month": mon, "day": day}) #前端代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试参数传递</title>
</head>
<body>
<h3>年份是: {{ year }}</h3>
<h3>月份是:{{ month }}</h3>
<h3>多少号:{{ day }}</h3>
</body>
</html>

错误处理

当Django 找不到一个匹配请求的URL 的正则表达式时,或者当抛出一个异常时,Django 将调用一个错误处理视图。

这些情况发生时使用的视图通过4个变量指定。 它们的默认值足以满足大多数项目,但可以通过覆盖其默认值进一步进行自定义。

Django中默认的错误视图对于大多数web应用已经足够了,但是如果你需要任何自定义行为,重写它很容易。 只要在你的根URLconf中指定下面的处理器(在其他任何地方设置它们不会有效)。

handler404覆盖了page_not_found()视图:
handler404 = 'mysite.views.my_custom_page_not_found_view'
handler500覆盖了server_error()视图:
handler500 = 'mysite.views.my_custom_error_view'
handler403覆盖了permission_denied()视图:
handler403 = 'mysite.views.my_custom_permission_denied_view'
handler400覆盖了bad_request()视图:
handler400 = 'mysite.views.my_custom_bad_request_view'

URL的扩展

当一个django工程中有多个app应用时,我们可以为每一个app单独设置其对应的url映射,然后再把对应app的urls.py文件包含在根urlconf中即可。

urlpatterns = [
url(r'^test', include("app01.urls")),
url(r'^bk', include("backend.urls")),
url(r'^cmdb', include("cmdb.urls")),
] #我们只需要在对应的app中定义urls.py文件即可,文件内容和根ruls.py文件类似。
#在根urlconf中捕获的任何参数,都可以传递给对应的子urlconf,进而可以传递给对应的视图函数。

URL传递额外的参数

urlpatterns = [
url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

#这个实例中不仅传递了关键字参数year,还传递了后面大括号中的关键字残血foo="bar",

url中使用include包含子url映射时,用法一样,可以直接跟在父url映射后,也可以直接跟在子url映射后面。

URL反向解析

在 Django 项目中经常需要获取最终形式的 URL,这么做是为了在生成的内容中嵌入 URL(视图和素材资源网址,呈现给用户的网址,等等), 或者用于在服务器端处理导航流程(重定向等)。

此时,一定不能硬编码 URL(费时、不可伸缩,而且容易出错), 或者参照 URL 配置创造一种生成 URL 的机制,因为这样非常容易导致线上 URL 失效。

换句话讲,我们需要的是一个 DRY 机制。 这种机制的一个优点是,当改进 URL 设计之后无需在项目源码中大范围搜索、替换失效的 URL。

Django 提供了一种方案,只需在 URL 映射中设计 URL。 我们为其提供 URL 配置,然后就可以双向使用:

  • 根据用户/浏览器发起的URL 请求,它调用正确的Django 视图,并从URL 中提取它的参数需要的值。
  • 根据Django 视图的标识和将要传递给它的参数的值,获取与之关联的URL。

第一种方式是我们在前面的章节中一直讨论的用法。 第二种方式叫做反向解析URL反向URL匹配反向URL查询或者简单的URL反查

在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:

  • 在模板中:使用url 模板标签。
  • 在Python代码中:使用reverse()函数。
  • 在更高层的与处理Django 模型实例相关的代码中:使用get_absolute_url() 方法。

上面摘自官网,直白一点,在form表单提交的时候action指向,我们不用再使用直接的url方式,而是在urlconf中给映射定义一个名字,然后再form表单中使用这个名字。有点就是当url映射关系更改时,只要名字不变,我们的form表单就不用更改。

一个简单的实例应用如下:

#url映射如下
url(r'^main/', main, name="enter_site"), #html代码中form提交如下:
<form action="{% url "enter_site" %}" method="post">

#注意格式的写法,名字要加上双引号。

在视图函数中,return返回的时候,要么返回的HttpResponse对象,要么返回的是经过render渲染过的html代码文件,还可以返回HttpResponseRedirect对象,指向一个url,而这个url就是在urlconf中配置的url,因此这里引用的时候我们可以直接返回url,也可以通过reverse函数返回。

urlconf中配置如下:
url(r'^info/', info, name="list_info"), 在视图函数中引用如下:
第一种直接引用url:
return HttpResponseRedirect("/info/")
第二种使用reverse函数:
from django.urls import reverse
return HttpResponseRedirect(reverse("list_info"))

#这两种方法的返回是一样的,推荐使用第二种。

使用name还有一个好处就是,我们知道在url解析时,可能有多个url可以指向一个视图,这是可以的,但是在反解析时,就会出问题了同一个视图有两个结果进行匹配。因此我们引入了name函数,给每一个url定义一个名字,在反解析时使用名字即可。

上面提到过在一个django工程中可能会有很多app,每个app下的url映射可能是重名的,这样即便定义了name(因为name重名)也会出问题,因此引入了命名空间的概念。

以下实例:

#根urlconf配置
urlpatterns = [
url(r'^mysite/', include("mysite.urls", namespace="mysite")), ] #mysite应用中url配置
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^main/', main, name="enter_site"),
url(r'^info/', info, name="list_info"),
url(r'^sign/([0-9]{4})/([0-9]{2})/$', sign),
url(r'^sign/(?P<year>[0-9]{4})/(?P<mon>[0-9]{2})/(?P<day>[0-9]{2})/$', sign),
] #form表单中url配置
<form action="{% url "mysite:enter_site" %}" method="post">
#注意这里的格式,命名空间与url名字之间用冒号隔开。 #视图函数中的应用
return HttpResponseRedirect(reverse("mysite:list_info"))
 
 
原文地址:https://www.cnblogs.com/wxzhe/p/10313675.html

Django的urls的配置的更多相关文章

  1. Django之urls.py路由配置(URLConf)

    urls.py路由配置(URLConf) URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表. 基本格式: Django1.x版本 ...

  2. Django基础之安装配置

    安装配置 一 MVC和MTV模式 著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据库的 ...

  3. django之urls系统

    Django的urls系统简介 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映 ...

  4. Django介绍、安装配置、基本使用、Django用户注册例子

    Django介绍     Django 是由 Python 开发的一个免费的开源网站框架,可以用于快速搭建高性能,优雅的网站     DjangoMTV的思想         没有controller ...

  5. django时区设置 media配置 日期截断函数 上传图片管理设计方案

    1.django时区 修改一下app里的设置 TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True # 不用UTC时间 USE_TZ ...

  6. Django框架 (一) 虚拟环境配置及简单使用

    虚拟环境 什么是虚拟环境 对真实的python解释器的一个拷贝版本 是事实有效的,可以独立存在运行解释python代码 可以在计算机上拷贝多个虚拟环境 为什么要使用虚拟环境 保证真实环境的纯净性 框架 ...

  7. Django中的路由配置简介

    Django中的路由配置简介 路由配置(URLconf)就是Django所支撑网站的目录.其实,我们利用路由交换中的"寻址"的概念去理解Django的路由控制会简单很多,它的本质就 ...

  8. Django之urls.py详解

    urls.py:URL分发器(路由配置文件)URL配置(URLconf)就像是Django所支撑网站的目录.它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表.你就是以这种方式告诉Dj ...

  9. Django 02 url路由配置及渲染方式

    Django 02 url路由配置及渲染方式 一.URL #URL #(Uniform Resoure Locator) 统一资源定位符:对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是 ...

  10. django (一) 环境的配置及Django文件简介

    1, 创建虚拟环境(virtualenv 和virtualenvwrapper) 1.1, virtualenv的概述 virtualenv是用来创建Python的虚拟环境的库,虚拟环境能够独立于真实 ...

随机推荐

  1. 免杀之:Python加载shellcode免杀

    免杀之:Python加载shellcode免杀 目录 免杀之:Python加载shellcode免杀 1 Python 加载Shellcode免杀 使用Python可以做一些加密.混淆,但使用Pyth ...

  2. ViT简述【Transformer】

    目录 结构概述 图像切patch Patch0 Position Embedding Multi-Head Attention 代码[Pytorch] Transformer在NLP任务中表现很好,但 ...

  3. swiper列数 slidesPerView属性决定

    swiper轮播一行有几列如下决定 slidesPerView为3是三列,不写一列 // 初始化文章swiper var newsSwiper = new Swiper('#news-swiper', ...

  4. golang输出字母a-z

    方法1: func main() { for i := 0; i < 10; i++ { ss := 'a' + i fmt.Printf("==%c", ss) } }

  5. Ubuntu 桌面系统升级

    背景 之前在学习 ROS2 时,安装 ros-humble-desktop 出现依赖错误:无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系. 依赖错误 该问题需要升级 Ub ...

  6. Vue进度条组件

    1.进度条颜色是渐变的 <template> <div id="progress_bar" ref="myChart"></div ...

  7. Prometheus监控操作

    一.架构说明 ➢ Prometheus Server:Prometheus 生态最重要的组件,主要用于抓取和存储时间序列数据, 同时提供数据的查询和告警策略的配置管理: ➢  Alertmanager ...

  8. HTML元素关系与CSS初步了解

    元素之间的关系 1.父子关系 父子关系就是在一个双标签内嵌套其他元素,那么嵌套在其中的元素就相当于"子",其外层元素相当于"父". <body>   ...

  9. Sublime Text3高效开发之编写代码块(snippet)

    看到别人使用HBuilder X可以插入代码块,就想sublime text3有没有类似的功能呢,诶还真有.在sublime text3叫作snippet. -snippet是干什么的?:可以在你编写 ...

  10. Java实现简单个人所得税计算器相关操作代码

    /** * 个税计算器 * 1.通过键盘输入用户的月薪 * 2.百度搜素个税计算方法,计算出应缴纳的税款 * 3.直到键盘输入88,则退出程序(使用break语句退出循环) * 应纳税所得额=工资收入 ...