目录:
url基本格式
url配置的本质是url与要为该url调用的视图函数之间的映射表
基本格式(1.*版本)
from django.conf.urls import url
urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]
参数说明
- 正则表达式:一个正则表达式字符串
- views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
- 参数:可选的要传递给视图函数的默认参数(字典形式)
- 别名:一个可选的name参数
django2.0语法区别
django2.X版本中有一个叫re_path()
ps:2.x中re_path就等价于1.x中的url
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
虽然path不支持正则表达式,但是它提供了五种转换器 (了解)
路径转换器
下列五种默认的转换器(官档翻译)
- str - 匹配任意非空字符串,除了路径分隔符‘/’,当转换器没有包括在表达式时,这是默认的。
- int - 匹配零或任意正整数。返回一个int
- slug - 匹配由ASCII字母或数字组成的任何slug字符串,以及连字符和下划线字符。 例如: building-your-1st-django-site 。
- uuid - 匹配格式化的UUID。 要防止多个URL映射到同一页面,必须包含短划线,并且字母必须为小写。 例如: 075194d3-6885-417e-a8a8-6c931e272f00。 返回一个UUID实例。
- path - 匹配任何非空字符串,包括路径分隔符’/’。 这允许您匹配完整的URL路径,而不是像str一样匹配URL路径的一部分。
url正则表达式
1.*django版本基本配置
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),
]
注意事项
- urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
- 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
- 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
- 每个正则表达式前面的’r’ 是可选的但是建议加上。
补充:如何开启URL访问地址后面不为/跳转至带有/的路径的配置项
Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加’/’。
APPEND_SLASH=True
例如urls.py:
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^blog/$', views.blog),
]
访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/ 。
如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时就会提示找不到页面。
url分组命名
可以使用分组命名匹配的正则表达式组来捕获URL中的值并以关键字参数形式传递给视图。
在Python的正则表达式中,分组命名正则表达式组的语法是(?Ppattern),其中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),
]
捕获的值作为关键字参数而不是位置参数传递给视图函数
**例如:**针对url /articles/2019/8/相当于按以下方式调用视图函数:
views.month_archive(request, year="2019", month="8")
在实际应用中,使用分组命名匹配的方式可以让你的URLconf 更加明晰且不容易产生参数顺序问题的错误,可以根据情况来使用
注意:捕获的参数永远都是字符串
url反向解析
根据Django 视图的标识和将要传递给它的参数的值,获取与之关联的URL。
在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:
- 在模板中:使用url模板标签。
- 在Python 代码中:使用django.core.urlresolvers.reverse() 函数。
- 在更高层的与处理Django 模型实例相关的代码中:使用get_absolute_url() 方法。
简单来说就是可以给我们的URL匹配规则起个名字,一个URL匹配模式起一个名字。
这样我们以后就不需要写死URL代码了,只需要通过名字来调用当前的URL。
示例:
url(r'^home', views.home, name='home'), # 给我的url匹配模式起名为 home
url(r'^index/(\d*)', views.index, name='index'), # 给我的url匹配模式起名为index
# 当有多个app存在的情况下,起别名的时候推荐你加上应用前缀
# 例如: url(r'^edit/(?P<edit_id>\d+)/',views.edit_view,name='app01_add')
在模板里面可以这样引用:
{% url 'home' %}
在views函数中可以这样引用:
from django.urls import reverse
reverse("index", args=("2018", ))
当url配置如下时:
from django.conf.urls import url
from . import views
urlpatterns = [
# ...
url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
# ...
]
模板内使用
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>
在视图函数内使用
from django.urls import reverse
from django.shortcuts import redirect
def redirect_to_year(request):
# ...
year = 2006
# ...
return redirect(reverse('news-year-archive', args=(year,)))
如果出于某种原因决定将URL调整一下,那么你将只需要修改URLconf 中的内容就可以完成需求
路由分发
当一个django项目下面有多个app的情况下,总的urls.py中路由与视图函数的对应关系太多 不便于管理
这个时候就可以再每个app下创建自己的urls.py,总的urls.py不再做对应关系,而只是做分发任务
每个app下都可以有自己的urls.py static文件夹 templates模板文件
也就意味着 每个app都可以被独立的开发出来 而不需要讨论交互(******)
示例1:
在urls.py中,使用include导入各个应用的urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls')),
]