在一个请求到达的时候,最先达到的就是视图层,然后根据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. 【GDKOI 2021提高组DAY2】抄写

    \(\text{Solution}\) \(dp\) 翻折就只需预处理回文中心 \(Manacher\) 预处理即可 \(Code\) #include<cstdio> #include& ...

  2. 空间数据库中ST_开头的来由

    1. 引言 在使用空间数据库(如,PostGIS)时,我们经常使用的空间函数(如,ST_Distance(geometry, geometry).ST_Area(geometry)等)都是以ST_开头 ...

  3. 一步步入门Jenkins+Net Core3.1+Gitlab,实现 CICD

    架构说明: 由浅入深,我们暂时不考虑分布式,安装Jenkins到用户服务器进行CICD 需要两台服务器 Gitlab:192.168.232.128:12080 源代码仓库,可以参考<安装git ...

  4. 【HTML】HTML特殊字符大全

    使用方法:这些字符属于unicode字符集,所以,你的文档需要声明为UTF-8:下面符号列表的后面有两列编号,它们并不太一样,第一列是用于html的,你需要在前面加上&#符号:第二列可以用于C ...

  5. python数据方面的文章

    excel 对接 jupyter      https://mp.weixin.qq.com/s/NTCIOs_Yz3MIRgT8S36yGQ pandas 常用分拆数据         https: ...

  6. 2022年了!还在用定时器实现动画?赶紧试试requestAnimationFrame吧!

    前言 作为一名前端开发者,相信你一定接触过动画.还记得最开始学习前端时,我们曾尝试使用 JS 实现各种动画效果,比如轮播图等等.随着前端技术的不断更新,我们实现动画的方式变得多种多样了,比如使用JS. ...

  7. Linux(CentOS) Mysql 8.0.30 安装(多源安装)

    Linux(CentOS) Mysql 8.0.30 安装(多源安装) 安装命令根据实际部署情况修改调整,CentOS一般选择通用版本Red Hat Enterprise Linux 7 本文档使用w ...

  8. window.location.href 用法总结

    想做好前端,这几种用法一定要了解: 在做网页前端的时候会经常用到JavaScript其中window.location.href用得非常多: 其中最常用的有windows.location.href= ...

  9. (app笔记)如何执行monkey命令测试稳定性

    1.monkeyMonkey 就是SDK中附带的一个工具,向系统发送伪随机的用户事件流,为了测试软件的稳定性.健壮性,验证app是否出现ANR or Crush 操作: 2. adb devices ...

  10. filebeat+Elk实现日志收集并使用kibana展示

    工作流程图 通过Filegeat收集日志,将日志的数据推送到kafka然后通过logstash去消费发送到Es,再通过索引的方式将数据用kibana进行展示: 1.部署测试机器规划 ip       ...