在一个请求到达的时候,最先达到的就是视图层,然后根据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. 单词检索(search)

    单词检索(search) \(Description\) 小可可是学校图书馆的管理员,现在他接手了一个十分棘手的任务. 由于学校需要一些材料,校长需要在文章中检索一些信息.校长一共给了小可可N篇文章, ...

  2. DomDom

    DomDom 目录 DomDom 1 信息收集 1.1 端口扫描 1.2 后台目录扫描 1.2.1 目录分析 2 GetShell 2.1 尝试命令执行 2.2 nc反弹shell失败 2.3 PHP ...

  3. Uncaught ReferenceError: Cannot access 'constantRouterMap' before initialization

    这个问题可以在 main.js 中,调整 import  store from '@/store 和  import router from @/router 的先后顺序进行解决 router 在 s ...

  4. unity通过隐藏layer隐藏组件

    设置组件layer 修改组件layer为需要隐藏的layer  隐藏组件 修改layer为隐藏状态 CenterCam.GetComponent<Camera>().cullingMask ...

  5. 测开-面试题-OS、Linux、算法、其他

    1 OS 1.1 进程.线程.协程区别? 答: 1.进程是资源分配的单位:2.线程是CPU调度的单位:3.协程是一种比线程更加轻量级的存在,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在 ...

  6. “const char*“类型的实参与“LPCWSTR-类型的形参不兼容

    const char *类型的实参与LPCWSTR类型的形参不兼容解决 LPCWSTR类型是是一个指向unicode编码字符串的32位指针,所指向字符串是wchar型(4字节,Unicode编码宽字节 ...

  7. django源码剖析(steup、runserver、生命周期)

    工作上会经常用到不熟悉的第三方模块,大多数时候会选择看文档.百度谷歌.看源码等形式去把它用起来.几年工作经验下来源码看的不少了,但当面试被问到django的生命周期时,只能浅谈根据wsgi协议会走ap ...

  8. 通过ESP8266WiFi模块调用“心知天气”接口 获取天气信息

    在分析代码之前,首先介绍 ArduinoJson 库的安装及"心知天气"的ID申请 一.安装 ArduinoJson 库 进入 Arduino 开发环境后,选择菜单栏-->工 ...

  9. asp.net core 全局授权管理系统简介

    大家好,我最近在做一个管理系统,我希望能做出一种授权机制,通过数据库的配置,来动态管控每个登入用于的访问权限. 因为才接触core不久,了解core的授权机制还是用了些时间的. 所以总结出来,供大家分 ...

  10. Kubernetes--管理资源标签(标签)

    随着同类型资源对象的数量越来越多,分类管理也变得越来越有必要:基于简单且直接的标准将资源对象划分为多个较小的分组,无论是对开发人员还是对系统工程师来说,都能提升管理效率,这也正是 Kubernetes ...