Django URLconf,简洁优雅的URL结构是高质量Web应用程序的象征。Django允许开发人员设计任何形式的URL,这在早期的网站中是不可想象的。早期的网站通常会有很长的一串URL,而且通常URL还会包括一些无用信息,如.aspx
、.php
等。
为了给应用程序设计URL,开发人员需要开发一个Python模块,这个模块就是URL的配置信息,通常我们将这个配置模块叫作URLconf。这个模块是一个纯粹的Python脚本,它包含了URL表达式与Python方法之间的映射,这里的Python方法就是Django应用中的视图方法。前面示例中的mysite/urls.py
和polls/urls.py
就是两个URLconf实例。
URLconf示例
下面是一个URLconf的简单示例:
示例解读:
- 函数path的第一个参数是一个URL模式字符串,用于匹配URL。
- 函数path的第二个参数是用于处理URL请求的视图函数。
- 使用尖括号提取URL中的参数,如
<int:year>
。 - 可使用类型转化器对参数类型进行转换,如int:会将从URL中捕获的值转换为数值类型,如果没有指定类型转换器,如
<year>
,则任何不包含/的字符串都会被提取。 - URL模式字符串不需要以
/
开头。
应用场景:
- 发送向
/articles/2005/03/
的请求将会与第三个URL模式字符串匹配成功,匹配成功后Django调用views.month_archive(request, year=2005, month=3)
。 - 发送向
/articles/2003/
的请求将会与第一个URL模式字符串匹配成功而不是第二个,因为Django在第一个URL匹配成功后停止后续URL检验,匹配成功后Django调用views.special_case_2003(request)
。 - 发送向
/articles/2003
的请求不会与任何URL模式字符串匹配成功,因为每个URL模式字符串都要求以/结束。 - 发送向
/articles/2003/03/building-a-django-site/
的请求将会与最后一个URL模式字符串匹配成功,匹配成功后Django调用views.article_detail(request, year=2003, month=3, slug="building-a-django-site")
。
URL参数类型转化器
前面提到可以使用int对捕捉到的URL参数进行类型转换,下面是Django支持的所有类型转换器。
- str:匹配任意非空字符串,但是不能匹配URL分隔符
“/”
。这是默认的URL参数转换器。 - int:匹配任意大于等于0的整数。
- slug:匹配任意slug字符串,slug字符串可以包含任意ASCII字符、数字、连字符
“-”
和下画线“_”
。 - uuid:匹配UUID字符串(字符串中的字母必须为小写字母),例如:
075194d3-6885-417e-a8a8-6c931e272f00
。 - path:匹配任意非空字符串,包括URL分隔符
“/”
。这允许匹配完成的URL而不是URL的一个片段。
自定义URL参数类型转化器
对于更加复杂的URL场景,开发人员可以开发自定义参数类型转换器,自定义参数类型转换器包括以下几部分:
- 一个regex属性,属性值为正则表达式。
- 一个
to_python(self, value)
方法,该方法用于将匹配的URL参数转换为指定类型,当类型转换失败后抛出ValueError异常。 - 一个
to_url(self, value)
方法,该方法用于将Python类型转换为类型转换器字符串。
下面是一个用于捕获日期年的类型转换器:
使用register_converter()
将以上类型转换器注册到URLconf。
创建视图:
def get_year(request, year):
return HttpResponse(str(year))
此时目录结构如下:
启动Web服务,访问URL,如图所示。
使用正则表达式
与Django 1.x一样,Django 2.0仍然可以使用正则表达式匹配URL,此时需要使用re_path()方法而不是path()。
Python的正则表达式支持对分组进行命名,语法格式为:(?P<name>pattern)
,其中name为分组名,pattern为匹配的正则表达式。
使用正则表达式对前面的URLconf进行重写效果如下:
虽然可以使用未命名的正则表达式,例如使用([0-9]{4})
替代(?P<year>[0-9]{4})
,但是为了防止出现意外错误,推荐对分组命名。
另外需要注意,不要将命名正则表达式与未命名正则表达式混合使用,这样会造成未命名正则表达式丢失。
最后正则表达式可以嵌套使用,如:
re_path(r'comments/(?:page-(?P<page_number>\d+)/)?$', comments)
导入其他URLconf
对于现代Web应用程序来说,一个工程下通常会包含多个应用程序,每个应用程序包含很多URL,如果将这些URL都写在URLconf根模块中,那么URLconf将会变得非常臃肿,不利于维护。对于这种情况,常用的解决办法就是为每一个应用程序写一套独立的URLconf,而URLconf根模块通过使用include()方法将其他URLconf引用进来。
下面是Polls网站的mysite/urls.py
:
当Django遇到include()方法时,URL匹配工作跳转进入被引用的URLconf进行验证。
使用include()方法还可以引用其他URL模式列表,例如:
此时访问/credit/reports/
时将会调用credit_views.report()
视图方法。这样做的好处是当一个应用程序中多条URL的前缀相同时,在本例中extra_patterns中的URL都是以credit开头,可以简化URL模式字符串。
酷客教程相关文章:
评论前必须登录!
注册