![Django项目开发实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/277/34233277/b_34233277.jpg)
4.1 配置URL
URL是用户访问网站的起点,对于一个想要成功的网站来说,URL是非常重要的一部分。如果想要用户被网站吸引,必须确保网址足够简单、简短且友好。Django框架对URL的设计没有限制,允许开发者根据需要设计URL。
4.1.1 URL匹配
要设计应用程序的URL,可以创建URLconf模块,这个模块用于将URL路径表达式映射到Python函数。当用户从Django支持的站点请求页面时,执行顺序如下。
(1)Django确定要使用的根URLConf模块,这通常由ROOT_URLCONF设置,但如果传入的HttpRequest对象具有urlconf属性(由中间件设置),将使用其替代ROOT_URLCONF设置。
(2)Django加载URLConf模块,并在其中查找urlpatterns变量。
(3)Django按顺序遍历每个URL模式,一旦找到匹配的模式,就停止遍历。
(4)Django调用该模式映射的视图函数。
(5)如果没有任何URL模式匹配,或者在此过程中抛出异常,Django将调用适当的错误处理视图。例如:
![](https://epubservercos.yuewen.com/1994DB/18320967408555206/epubprivate/OEBPS/Images/Figure-P79_6766.jpg?sign=1738960107-V43BunhADQQ3pTflhFgiC3CpfKJ8m7LL-0-b35ab36a9963a38aa351f9b52cbda822)
分析:
- 如果想从URL捕获值,则要使用尖括号。
- 捕获的值可以包括转换器类型。
- 对/categories/2018的请求会匹配到第二条规则,Django会调用方法views.category_detail(request,2018)。
可以使用命名的正则表达式组来捕获URL并将它们作为关键字参数传递给视图。在Python中,命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。下面我们用正则模式来改写上面的例子:
![](https://epubservercos.yuewen.com/1994DB/18320967408555206/epubprivate/OEBPS/Images/Figure-P79_6768.jpg?sign=1738960107-LMgqaMKsU6vMchzaSSef9RkFt7iGDRDv-0-28661eb0a816fcb466f6ee82ffc609ca)
以上代码实现的效果和前面的例子完全相同,只有一个细微的区别:捕获的值作为关键字参数而不是位置参数传递给视图函数。请求/categories/2018将会调用函数views.category_detail(request,categorey_id=2018)。
值得注意的是,无论正则表达式匹配什么类型,每个捕获的参数都作为普通Python字符串传递给视图函数。
在Django 2.1版本中,普通匹配使用path( )方法,正则匹配使用re_path( )方法来替代1.8版本中的url( )方法。在使用url( )方法匹配的时候需要注意Django的版本。
4.1.2 配置嵌套
urlpatterns可以包含其他URLconf模块,模块和模块之间会构成层级关系,示例代码如下:
![](https://epubservercos.yuewen.com/1994DB/18320967408555206/epubprivate/OEBPS/Images/Figure-P79_6772.jpg?sign=1738960107-3VTEeb34xmi21FMvpkShAOQlLEGp4EiL-0-41c0a0de9eb55917acbd5a0e696c36c5)
注意,在上面的例子中,正则表达式并不包含“$”,多了“/”。每当Django遇到django.conf.urls.include( )方法时,它会删除与该点匹配的URL部分,并将剩余的字符串发送到包含的URLconf以进行进一步处理。
另一种可能性是include只包含url( )实例的列表,如下面的配置代码:
![](https://epubservercos.yuewen.com/1994DB/18320967408555206/epubprivate/OEBPS/Images/Figure-P80_6823.jpg?sign=1738960107-7XA27o1OufD6npUKOEP3JGT0x4fuRHdp-0-dd841435ea492a0ee40c59a60fd2552a)
在上面的例子中,对/credit/reports/的请求会被credit_views.report视图函数处理。采用配置嵌套有助于URL的管理,删除冗余。
4.1.3 反向解析URL
在Django项目中,一个常见的需求是获得最终形式的URL字符串,将其嵌入生成的内容中,用来导航。
实现这个效果最简单的方式是在内容中写死URL,但这种方法费力,容易出错又不可扩展。在文档中写死业务URL会出现文档过时的问题。
Django提供了反向解析URL的功能来避免URL容易过时的问题。除此之外,这个功能还为开发提供了便捷,因为用户不再遍历所有项目源代码来搜索和替换过时的URL。
要做到反向解析URL,首先要对URL进行标识,如为URL起一个独一无二的名字。另外还需要知道正确的URL及对应的视图参数类型和值。这样,URLconf模块就有了两个作用:
- 根据用户请求的URL,找到正确的视图函数,执行业务逻辑。
- 标识相应的Django视图及传递给它的参数,获取相关的URL。
第一个作用在前面已经学习过了,现在来学习第二个作用。Django提供了用于执行URL反转的工具,这些工具在不同的层次中。
- 在模板中,使用URL模板标签。
- 在业务代码中,使用django.core.urlresolvers.reverse( )函数。
- 在处理与Django模型实例相关URL的更高级代码中,使用get_absolute_url( )方法。
下面来看一个例子,还是使用之前用过的URLconf:
![](https://epubservercos.yuewen.com/1994DB/18320967408555206/epubprivate/OEBPS/Images/Figure-P81_6874.jpg?sign=1738960107-jGsThNs3QhM47v6UWKWq1Bu3CxSiOGOw-0-6a6daeb8fb38582bd118dfe5847db84d)
在模板中可以使用URL标签,带上签名设置的名字和参数,就能生成真实的连接。示例代码如下:
![](https://epubservercos.yuewen.com/1994DB/18320967408555206/epubprivate/OEBPS/Images/Figure-P81_6876.jpg?sign=1738960107-OFACFGl9XC9LoMt9vnWhYM8P9UMoQsyK-0-1d4f503c38823f3567e558c834cb8964)
在视图代码中可以使用reverse( )方法,传入URLconf中定义的名字和参数,生成实际使用的链接。示例代码如下:
![](https://epubservercos.yuewen.com/1994DB/18320967408555206/epubprivate/OEBPS/Images/Figure-P81_6878.jpg?sign=1738960107-ztEPvQQQOIa1pL9QTjJZKfslJEcrtt7s-0-95d4c899a822603526501b3ceed65ab8)
如果有一天请求详情品类的URL发生改变,那么只需要修改URLconf模块,其他的地方不用修改。