URLConf配置
-
基本格式
from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图,参数,别名), ]
##########django中1.11版本用法########### 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), ]
-
参数说明
- 正则表达式:一个正则表达式字符串
- views视图:一个可调用函数,通常为一个视图函数
- 参数:可选的要传递给视图函数的默认参数,字典的形式
- 别名:一个可选的name参数。
注:
############Django 2.0版本中的路由系统是下面的写法########### from django.urls import path,re_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), ] # 2.0版本中re_path和1.11版本的url是一样的用法。
正则表达式(动态路由)
-
常用正则:
# 详情参看re模块-正则表达式 ^ 以什么开头 $ 以什么结尾 [0-9] 数字0-9都可以,只表示一位 # []里面不论写多少,都表示一位 [a-zA-Z] a-Z中的任意一个 d 表示所有数字 w 表示大小写字母,数字,下划线 . 表示除换行外的所有内容 * 表示匹配0次或多次 + 表示匹配1次或多次 ? 表示匹配0次或1次
-
基本配置
from django.conf.urls import url from app01 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中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再匹配。
urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^blog/', views.blog), # 这个地址可以匹配只要是bolg/这个地址的,不管后面有没有东西都会匹配出 # 所以如果输入blog/9999/这个地址时按从上往下依然会匹配blog/这个地址。 url(r'^blog/[0-9]{4}/$', views.blogs), ] 注:为了不出现错误,最好在末尾都加上$,遇到/就结束匹配,如:r'^blog/$'
若要从url中捕获一个值,只需要在他周围放置一对圆括号(分组匹配)。
url(r'^blog/([0-9]{4})/$', views.blogs)
不需要添加一个前导的反斜杠,因为每个
url
都有。url(r'^blog/', views.blog) # ^blog/ 而不是 ^/blog/
每个正则表达式前面都加
‘r’
,可选但是建议都加上。 -
严格匹配
# 是否开启URL访问地址后面不写/跳转至带有/的路径的配置项 APPEND_SLASH=True
Django settings.py
配置文件中默认没有APPEND_SLASH
这个参数,但Django
默认这个参数为APPEND_SLASH = True
。 其作用就是自动在网址结尾加'/'。当输入网址http://www.example.com/blog时,会自动跳转http://www.example/com/blog/ # 如果不想让其自动加/,则在setting文件中写入 APPEND_SLASH=False 当输入网址http://www.example.com/blog时,会找不到页面 http://www.example/com/blog/
-
分组
# urls文件中的映射列表 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^xxx/$', views.blog), url(r'^xxx/([0-9]{3})/$',views.blogs), ] # views中的函数 def blogs(request): return render(request,'yyy.html')
# 同上 url(r'^xxx/([0-9]{3})/$',views.blogs), # views中的函数 访问的url:http://127.0.0.1:9000/xxx/999/ def blogs(request,num): print(num,type(num)) return render(request,'yyy.html')
注:说明分组中的内容按照位置参数传给了视图函数,捕获的参数永远都是字符串,因为路径是字符串,从路径中捕获的也是字符串。
-
命名分组
注:命名分组中的内容按照关键字参数传给了视图函数,捕获的参数永远都是字符串,因为路径是字符串,从路径中捕获的也是字符串。
# urls文件中的映射列表 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^xxx/$', views.blog), url(r'^xxx/(?P<num>[0-9]{3})/$',views.blogs), ] # views中的函数 def blogs(request): return render(request,'yyy.html')
# views中的函数 def blogs(request,num): print(num) return render(request,'yyy.html')
视图函数中指定默认值
-
如下:当不传参数时,默认访问参数
num=1
的页面,传参数时,访问参数的页面 -
应用:如不传参数时访问首页,传入参数时,访问其他页面。
# urls文件中的映射列表 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^xxx/$', views.blog), url(r'^xxx/(?P<num>[0-9]{3})/$',views.blogs), ] # views中的函数 def blogs(request,num=1): return render(request,'yyy.html')
include(路由分发)
-
将根的路由分发到每个功能。
-
不分发的写法
# urls文件中的映射列表 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^xxx/$', views.blog), url(r'^xxx/(?P<num>[0-9]{3})/$',views.blogs), ]
-
路由分发后的写法
根的urls文件
from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/', include('app01.urls')), # 将路由分发给app01中的urls ]
app01中的urls文件
from django.conf.urls import url, include from . import views urlpatterns = [ url(r'^blog/$', views.blog), url(r'^blog/(?P<year>[0-9]{4})/(?P<month>d{2})/$', views.blogs), ] # 以上访问的路径就是'app01/blog/'和'app01/blog/?year=1&month=1'
传递额外的参数给视图函数
# urls文件中的映射列表
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^xxx/$', views.blog),
url(r'^xxx/(?P<num>[0-9]{3})/$',views.blogs,{'second':888}), # 使用字典传参,原始value是什么类型,视图函数获取到的值就是什么类型。
]
# views中的函数
def blog(request,num):
return render(request,'yyy.html')
url(r'^xxx/(?P<num>[0-9]{3})/$',views.blogs,{'second':888}), # 使用字典传参,原始value是什么类型,视图函数获取到的值就是什么类型。
# views中的函数
def blogs(request,num,second):
return render(request,'yyy.html')
注:这种方式是直接传的参数,所以传过去的是什么类型,接收的就是什么类型。
URL命名和反向解析
-
命名分组
# urls文件中的映射列表 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^blog/$', views.blog), url(r'^blog/(?P<num>[0-9]{3})/$',views.blogs,name='xxx'), ]
-
反向解析
通过别名找到要访问的路径
静态路由
url(r'^blog/$', views.blog, name='blog'), # 在模板中,html文件 {% url '别名' %} --> 即访问'/blog/'完整的地址 如:{% url 'blog' %} # 在视图函数中,py文件 from django.urls import reverse # 先导入方法 reverse('别名') --> 即访问'/blog/'完整的地址 如:reverse('blog')
分组
url(r'^blog/([0-9]{4})/(d{2})/$', views.blogs, name='blogs'), # 在模板中反向解析 {% url 'blog' 2222 12 %} # 即访问 /blog/2222/12/ 地址 # 在视图函数中,py文件 from django.urls import reverse # 先导入方法 reverse('别名',args = ('2222','12')) # 即访问 /blog/2222/12/ 地址
命名分组
url(r'^blog/(?P<year>[0-9]{4})/(?P<month>d{2})/$', views.blogs, name='blogs') # 在模板中的反向解析 {% url 'blogs' 2222 12 %} # 即访问 /blog/2222/12/ 地址 {% url 'blog' year=2222 month=12 %} # 在视图函数,py文件中 from django.urls import reverse # 先导入方法 reverse('别名',args = ('2222','12')) # 即访问 /blog/2222/12/ 地址 reverse('blogs',kwargs = {'year':2222,'month':12})
-
namespace命名空间模式
即使不同的APP使用相同的URL名称,URL的命名空间模式也可以让你找到唯一反转命名的URL。
# project中的urls urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^app01/', include('app01.urls', namespace='app01')), url(r'^app02/', include('app02.urls', namespace='app02')), ]
# app01中的urls from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^(?P<pk>d+)/$', views.detail, name='detail') ]
# 在模板中的反向解析 {% url 'app01:blogs' 2222 12 %} # 即访问 /app01/blog/2222/12/ 地址 {% url 'app01:blog' year=2222 month=12 %} # 在视图函数,py文件中 from django.urls import reverse # 先导入方法 reverse('app01:别名',args = ('2222','12')) # 即访问 /app01/blog/2222/12/ 地址 reverse('app01:blogs',kwargs = {'year':2222,'month':12}) 注:在别名前面都加上命名空间namespace