python分析路由器配置文件_python之路 - day58 Django-路由 (分组、路由分发、反向解析)...

Django路由

1.简单的路由配置

from django.contrib importadminfrom django.urls importpath, re_path#django 2.往后的版本,要使用正则,需要引入re_path

#必须导入自己创建的应用里的views视图.py文件

from app01 importviews

urlpatterns=[#根据客户端请求的路径,分配路由。

#path()是完全匹配,re_path()是使用正则匹配

#path("login/")相当于re_path(r"^login/$") 路径指定以l开头,以/结尾

re_path(r'^articles/2003/$', views.special_case_2003),

path("articles/2003/",views.special_case_2003),

]

注意:

若要从URL 中捕获一个值,使用re_path(),需要在正则里的周围放置一对圆括号(分组)。

不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。

每个正则表达式前面的'r' 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义

正则里最好使用 ^ 和 $ 来约束开头和结尾

2.  re_path( )里的正则,使用无名分组,获取url中需要的参数

使用re_path() 正则里的分组,来获取GET请求中,url路径中需要的部分参数,便于在视图(views.py的函数)里使用。

注意: 无名分组,一个正则中匹配的多个分组项,是按位置和视图函数一一对应的

urls.py内容如下:

from django.contrib importadminfrom django.urls importpath, re_path#django 2.往后的版本,要使用正则,需要引入re_path

#必须导入自己创建的应用里的views视图.py文件

from app01 importviews

urlpatterns=[#根据客户端请求的路径,分配路由。

#path()是完全匹配,re_path()是使用正则匹配

#path("login/")相当于re_path(r"^login/$") 路径指定以l开头,以/结尾

#【重要】 re_path里的正则表达式里,如有()进行了分组,则匹配成功后,会将匹配的分组内容,当作参数,调用views.py里对应的函数

re_path(r"^articles/2003/$", views.special_year), #special_year(request)

re_path(r"^articles/(\d{4})/$", views.year_archive), #year_archive(request,'2020')

re_path(r"^articles/(\d{4})/(\d{2})/$", views.year_month_archive), #year_archive(request,'2020','01')

#【注意】路由很多时,一定要注意上下匹配先后问题,程序从上往下执行,一旦匹配成功,马上执行,后面的即使能匹配,也不执行了。

#浏览器输入: https://127.0.0.1:8000/articles/2003/ 调用views.py里的 special_year(request),而不是调用 year_archive(request,'2003'),因为只执行一次匹配

#浏览器输入: https://127.0.0.1:8000/articles/2020 调用views.py里的 year_archive(request,'2020')

#浏览器输入: https://127.0.0.1:8000/articles/2020/01 调用views.py里的 year_month_archive(request,'2020','01')

]

views.py内容如下:

from django.shortcuts importrender,HttpResponse#render是一个函数,HttpResponse是一个类

#Create your views here.

importtime,datetimedefspecial_year(request):#去数据库查询所有2003年的文章

return HttpResponse("special_year:2003 OK")defyear_archive(request,year): #这里的year拿到的是 字符串类型#去数据库查询所有指定年份的文章

returnHttpResponse(year)defyear_month_archive(request,year,month):#去数据库查询指定年、指定月份的文章

return HttpResponse("year:%s month:%s" %(year,month))

使用浏览器访问:

-----

----

3.有名分组 (对比上面的无名分组)

正则里使用 ( )进行分组

使用 ?P< 关键字> 来给该分组起名字

urls.py如下:

from django.contrib importadminfrom django.urls importpath, re_path#django 2.往后的版本,要使用正则,需要引入re_path

#必须导入自己创建的应用里的views视图.py文件

from app01 importviews

urlpatterns=[#根据客户端请求的路径,分配路由。

#path()是完全匹配,re_path()是使用正则匹配

#path("login/")相当于re_path(r"^login/$") 路径指定以l开头,以/结尾

#无名分组

#re_path(r"^articles/(\d{4})/(\d{2})/$", views.year_month_archive), # year_archive(request,2020,01)

#有名分组 ()用来分组; ?P用来给该分组起个名字(关键字)

re_path(r"^articles/(?P\d{4})/(?P\d{2})/$", views.year_month_archive2), #year_archive2(request,year='2020',month='01')]

views.py如下:

from django.shortcuts importrender,HttpResponse#render是一个函数,HttpResponse是一个类

defspecial_year(request):#去数据库查询所有2003年的文章

return HttpResponse("special_year:2003 OK")defyear_archive(request,year):#去数据库查询所有指定年份的文章

returnHttpResponse(year)def year_month_archive(request,year,month): #无名分组时,year 和 month 的前后位置关系,必须和路由里的正则匹配时一样。 另外,无名分组的函数里,参数名可以随便起,例如 year_month_archive(request,y,m)也是可以的。

#去数据库查询指定年、指定月份的文章

return HttpResponse("year:%s month:%s" %(year,month))def year_month_archive2(request,month,year): #有名分组时,year和month参数,顺序就可以打乱写了。 有名分组里的函数的参数名,必须和正则里的分组名一样,否则函数调用时会报错。

#去数据库查询指定年、指定月份的文章

return HttpResponse("year:%s month:%s" %(year,month))

4.路由分发 (适合较大项目,项目下有多个应用)

当项目较大时,再使用全局的urls.py来分发到多个不同应用的视图函数,会降低阅读、维护的难度。

所以,可以通过全局urls.py首先根据应用,进行首次路由分发到各个应用的urls.py。到达应用层后,再由各个应用的urls.py进行分发到视图函数。

4.1 全局 url.py

#全局 urls.py

from django.urls importpath, re_path, include#django 2.往后的版本,要使用正则,需要引入re_path

#如果项目较大,有多个应用,则在全局的路由里,需要进行一次路由分发,即发送到各个应用的路由。需要引入include()函数

urlpatterns=[#根据客户端请求的路径,首先分配到各个应用的路由。

#此示例中,整个项目首页,也分发在一个应用里,该应用只用来显示主页

re_path("^$",include("app_index.urls")), #以空开头,以空结尾,匹配根目录。一般用来显示主页等。

#根据项目里的应用,进行路由分发

re_path('app01/', include('app01.urls')), #从url从匹配到 "app01"后,将后面的路径,分发到 app01.url.py的路由里

re_path('app02/', include('app02.urls')), #从url从匹配到 "app02"后,将后面的路径,分发到 app02.url.py的路由里

]

全局 urls.py

4.2 各应用的 urls.py (需要自己创建该.py文件。可以直接复制全局的代码过来,稍作修改)

app01的urls.py:

app02的urls.py:

app_index的 urls.py:

#app01的urls.py

from django.contrib importadminfrom django.urls importpath, re_path#django 2.往后的版本,要使用正则,需要引入re_path

#必须导入自己创建的应用里的views视图.py文件

from app01 importviews

urlpatterns=[

re_path("^$", views.index), #分发到 应用app01的首页

re_path(r"^articles/2003/$", views.special_year), #special_year(request)

re_path(r"^articles/(\d{4})/$", views.year_archive), #year_archive(request,'2020')

#有名分组 ()用来分组; ?P用来给该分组起个名字(关键字)

re_path(r"^articles/(?P\d{4})/(?P\d{2})/$", views.year_month_archive2), #year_archive2(request,year='2020',month='01')

]

# app01的urls.py

#app02的 urls.py

from django.contrib importadminfrom django.urls importpath, re_path#django 2.往后的版本,要使用正则,需要引入re_path

#必须导入自己创建的应用里的views视图.py文件

from app02 importviews

urlpatterns=[

re_path("^$",views.index), #分发到 应用app02的首页

re_path("^timer/$",views.timer),

]

# app02的urls.py

#app_index 的 urls.py

from django.contrib importadminfrom django.urls importpath, re_path#django 2.往后的版本,要使用正则,需要引入re_path

#必须导入自己创建的应用里的views视图.py文件

from app_index importviews

urlpatterns=[

re_path("^$", views.index), #发到 应用app_index的首页,此示例,把此应用的首页,作为整个项目的首页

]

# app_index的 urls.py

4.3 各应用的 views.py

4.4 使用浏览器访问:

==

==

==

#app_index的views.py

from django.shortcuts importrender,HttpResponse#render是一个函数,HttpResponse是一个类

#Create your views here.

#函数1 主页

defindex(request):return HttpResponse("项目 主页")

# app_index的views.py

#app01 的views.py

from django.shortcuts importrender,HttpResponse#render是一个函数,HttpResponse是一个类

#Create your views here.

importtime,datetimedefspecial_year(request):#去数据库查询所有2003年的文章

return HttpResponse("special_year:2003 OK")defyear_archive(request,year):#去数据库查询所有指定年份的文章

returnHttpResponse(year)def year_month_archive(request,year,month): #无名分组时,year 和 month 的前后位置关系,必须和路由里的正则匹配时一样

#去数据库查询指定年、指定月份的文章

return HttpResponse("year:%s month:%s" %(year,month))def year_month_archive2(request,month,year): #有名分组时,year和month参数,顺序就可以打乱写了。

#去数据库查询指定年、指定月份的文章

return HttpResponse("year:%s month:%s" %(year,month))

# app01 的views.py

#app02 的views.py

from django.shortcuts importrender,HttpResponse#render是一个函数,HttpResponse是一个类

#Create your views here.

importtime,datetime#函数1 主页

defindex(request):return HttpResponse("app02 主页")#函数2 显示当前时间给前端

deftimer(request):

now=str(datetime.datetime.now())return HttpResponse("app02 当前时间:"+now)

# app02 的views.py

5. 反向解析 (可以理解为在路由分发时,使用 别名) ---- 别名在html文档里的应用

1.url路由里,设置 别名

2.视图函数里,执行render(request,'login.html')时,django将检索特殊语法,将html里的特殊语法进行替换

3.html文件 表单提交时的 url使用 {% url '别名' %},来替代直接写死的方式

4.当对外的接口发生变化时,需要修改的代码量就很少。使用浏览器访问如下:

------

6.反向解析 (可以理解为在路由分发时,使用 别名) ---- 别名在html文档里的应用2 (路由里包含分组的动态参数时)

在上面的正则中,没有分组的动态参数。当正则中含有分组的动态参数时,html里使用别名时,就必须配上对应的参数

7.反向解析 的另一应用场景 -----  别名在views.py视图函数里的应用1

1.在urls.py里设置路径别名

2. 在views.py里,导入 reverse方法

from django.urls import reverse

8.反向解析 的另一应用场景 -----  别名在views.py视图函数里的应用2

上面第7点,正则中没有分组的动态参数。

现在,如果正则里有分组的动态参数,则在views.py中,使用 reverse()时,必须传入 args=(参数1,参数2...)

总结:

路径使用别名的好处: 假如我们的视图函数、或者html模板中有用到路径,如果把路径写死成固定字符串,一旦后期对外接口发生变化,我们用到此路径的地方,也必须手动同步修改,维护难。使用别名,则很好的解决了这种问题。

--

--------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值