Django2.X—路由定义规则
一个完整的路由包含:路由地址、视图函数(或者视图类)、可选变量和路由命名。
1、路由定义规则
路由称为URL,是对可以从互联网上得到的资源位置和访问方法的一种简洁的表示,是互联网标准资源的地址。互联网上的每个文件都有一个唯一的路由,用于指出网络文件的路径位置。简单说,路由可视为我们常说的网址,每个网址代表不同的网页。
1.1 Django2.X路由定义
这种路由设计模式下,工作原理如下:
- 运行MyDjango项目时,Django从MyDjango文件夹的urls.py找到各个App所定义的路由信息,生成完整的路由列表。
- 当用户在浏览器*问某个路由地址时,Django就会收到该用户的请求信息。
- Django从当前请求信息获取路由地址,并在路由列表里匹配相应的路由信息,再执行路由信息所指向的视图函数(或视图类),从而完成整个请求响应过程。
MyDjango文件夹的urls.py代码如下:
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
# 指向内置Admin后台系统的路由文件sites.py
path('admin/',admin.site.urls),
# 指向index的路由文件urls.py
path('',include('index.urls')),
]
MyDjango文件夹的urls.py定义两条路由信息,分别是Admin站点管理和首页地址(index)。其中,Admin站点管理在创建项目时已自动生成,一般情况下无需修改;首页地址是指index文件夹的urls.py。MyDjango文件夹的urls.py的代码解释如下:
- from django.contrib import admin:导入内置Admin功能模块。
- from django.urls import path,include:导入Django的路由函数模块。
- urlpatterns:代表整个项目的路由集合,以列表格式表示,每个元素代表一条路由信息。
- path(‘admin/’,admin.site.urls):设定Admin的路由信息。'admin/'代表127.0.0.1:8000/admin的路由地址,admin后面的斜杠是路径分隔符,其作用等同于计算机中文件目录的斜杆符号;admin.site.urls指向内置Admin功能所自定义的路由信息,可以在Python目录Lib\site-packages\django\contrib\admin\sites.py找到具体定义过程。
- path(’’,include(‘index.urls’)):路由地址为“\”,即127.0.0.1:8000,,通常是网站的首页;路由函数include是将该路由信息分发给index的urls.py处理。这里的index的urls.py来源在前面博客中讲到了。
由于首页地址分发给index的urls.py处理,因此下一步需要对index的urls.py编写路由信息。如下:
# index的urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.index)
]
index的urls.py的编写规则与MyDjango文件夹的urls.py大致相同,这是最为简单的定义方法,此外可参考内置Admin功能的路由定义方法。
在index的urls.py导入index的views.py文件,该文件用于编写视图函数或视图类,主要用于处理当前请求信息并返回响应内容给用户。路由信息path(’’,views.index)的views.index是指视图函数index处理网站首页的用户请求和响应过程。因此,在index的views.py中编写index函数的处理过程,代码如下:
from django.shortcuts import render
def index(request):
return render(request,'index.html')
index函数必须设置一个参数,参数命名不固定,但常以request进行命名,代表当前用户的请求对象,该对象包含当前请求的用户名、请求内容和请求方式等。
视图函数执行完成后必须使用return将处理结果返回,否则程序会抛出异常信息。启动MyDjango项目,在浏览器里访问即可。
路由文件urls.py的路由定义规则是相对固定的,路由列表由urlpatterns表示,每个列表元素代表一条路由。路由由Django的path函数定义的,该函数第一个参数是路由地址,第二个参数是路由所对应的处理函数(视图函数或视图类),这两个参数是路由定义的必选参数。
1.2 路由变量的设置
在日常开发过程中,有时一个路由代表多个不同的页面,如编写带有日期的路由,若根据前面的编写方式,按一年计算,则需要开发者编写365个不同的路由才能实现,实现这种做法明显是不可取的。因此,Django在定义路由时,可以对路由设置变量值,使路由具有多样性。
路由的变量类型有字符类型、整型、slug和uuid,最为常用的使字符类型和整型。各个类型说明如下:
- 字符类型: 匹配任何非空字符串,但不含斜杆,如果没有指定类型,就默认使用该类型。
- 整型: 匹配0和正整数。
- slug: 可理解为注释、后缀或附属等概念,常作为路由的解释性字符。可匹配ASCII字符以及连接符和下画线,能使路由更加清晰易懂。比如网页的标题是"14岁的小娃娃",其路由地址可以设置为“14-sui-de-xiaowawa”。
- uuid: 匹配一个uuid格式的对象。为了防止冲突,规定必须使用“-”并且所有字母必须小写,例如:075446e5-4646-fajkl46468
根据上述变量类型,在MyDjango项目的index文件夹的urls.py里新定义路由,并且带有字符类型、整型和slug的变量,代码如下:
# index的urls.py文件
from django.urls.import.path
from . import views
urlpatterns = [
# 添加带有字符类型、整型和slug的路由
path('<year>/<iny:month>/<slug:day>',views.myvariable)
]
在路由中,使用变量符号“<>”可以为路由设置变量。在括号里面以冒号划分为两部分,冒号前面代表的是变量的数据类型,冒号后面代表的是变量名,变量名可自行命名,如果没有设置变量的数据类型,就默认为字符类型。上述代码设置了3个变量,分别是<year>、<int:month>和<slug:day>,变量说明如下:
- <year>:变量名为year,数据格式为字符类型,与<str:year>的含义一样。
- <int:month>:变量名为month,数据格式为整型。
- <slug:day>:变量名为day,数据格式为slug。
在上述新增的路由中,路由的处理函数为myvariable,因此在index的views.py中编写myvariable的处理过程,代码如下:
# views.py的myvariable函数
from django.http import HttpResponse
def myvariable(request,year,month,day):
return HttpResponse(str(year)+'/'+str(month)+'/'+str(day))
启动项目,在浏览器上输入127.0.0.1:8000/2020/04/19,运行结果则输出2020/4/19。如果浏览器输入的路由地址与其变量类型不相符合,Django就会提示Page not found。路由的变量和视图函数的参数要一一对应,如果视图函数的参数与路由的变量对不上,那么程序会抛出不相符的报错信息。
除了在路由地址设置变量外,Django还支持在路由地址外设置变量(路由的可选变量)。在index的urls.py和views.py中分别新增路由和视图函数。代码如下:
# index的urls.py
from django.urls import path
from . import views
urlpatterns = [
# 添加带有字符类型、整型和slug的路由
path('<year>/<iny:month>/<slug:day>',views.myvariable),
# 添加路由地址外的变量month
path('',views.index,{'month':'2019/10/10'})
]
# index的views.py
from django.http import HttpResponse
def myvariable(request,year,month,day):
return HttpResponse(str(year)+'/'+str(month)+'/'+str(day))
def index(request,month):
return HttpResponse('这是路由地址之外的变量:'+month)
从上述代码可以看出,路由函数path的第3个参数是{‘month’:‘2019/10/10’},该参数的设置则如下:
- 参数只能以字典的形式表示。
- 设置的参数只能在视图函数中读取和使用。
- 字典的一个键值对代表一个参数,键值对的键代表参数名,键值对的值代表参数值。
- 参数值没有数据格式限制,可以为某个实例对象,字符串或列表(元组)等。
视图函数index的参数必须对应字典的键,如果字典里设置两对键值对,视图函数就要设置相应的函数参数,否则在浏览器*问的时候就会提示报错信息。
1.3 正则表达式的路由定义
前面设置路由地址分别代表日期的年、月、日,其变量类型分别是字符类型、整型和sulg,因此在浏览器上输入127.0.0.1/AAAA/05/01是合法的,但是不符合日期格式要求。为了进一步规范日期格式,可以使用正则表达式限制路由地址变量的取值范围。在index文件夹的urls.py里使用正则表达式定义路由地址,代码如下:
from django.urls import re_path
from . import views
urlpatterns = [
re_path('(?P<year>[0-9]{4})/(?P<month>[0-9]{2}/(?P<day>[0-9]{2})).html',views.mydate)
]
路由的正则表达式是由路由函数re_path定义的,其作用是对路由变量进行截取与判断,正则表达式是以小括号为单位的,每个小括号的前后可以使用斜杆或者其他字符将其分隔与结束。以上代码为例,分别将变量year、month和day以斜杆隔开,每个变量以一个小括号为单位,在小括号内,可分为3部分,以(?P<year>[0-9]{4})为例。
- ?P是固定格式,字母P必须为大写。
- <year>为变量名
- [0-9]{4}是正则表达式的匹配模式,代表变量的长度为4,只允许取0~9的值。
上述路由的处理函数mydate函数,因此还需要在index的views.py中编写视图函数mydate,代码如下:
# views.py的mydate函数
from django.http import HttpResponse
def mydate(request,year,month,day):
return HttpResponse(str(year)+'/'+str(month)+'/'+str(day))
路由地址末端设置了".html",这是一种伪静态URL技术,可将网址设置为静态网址,用于SEO搜索引擎的爬取,如百度、谷歌等。此外,在末端设置".html"是为变量day设置终止符,假如末端没有设置".html",在浏览器上输入无限长的字符串,路由也能正常访问。