Django3 web应用开发实战黄永祥章节总结
路由(三)路由的使用方式
-
在模板中使用路由
-
反向解析reverse与resolve
-
路由重定向
在《精通Django 3 Web开发3.1设置路由分发规则》中写到:
从MyDjango文件夹的urls.py定义的路由信息得知,每个项目应用(App)的路由地址交给项目应用的urls.py自行管理,这是路由的分发规则,使路由按照一定的规则进行分类管理。整个路由设计模式的工作原理说明如下:
(1)当运行babys项目时,Django从babys文件夹的urls.py找到各个项目应用(App)的urls.py,然后读取每个项目应用(App)的urls.py定义的路由信息,从而生成完整的路由列表。
(2)用户在浏览器*问某个路由地址时,Django就会收到该用户的请求信息。
(3)Django从当前请求信息中获取路由地址,并在路由列表里匹配相应的路由信息,再执行路由信息所指向的视图函数(或视图类),从而完成整个请求响应过程。
django的路由命名name是对路由进行命名,其作用是在开发过程中可以在视图或模板等其他功能模块里使用路由命名name来生成路由地址。
命名空间namespace可以为我们快速定位某个项目应用的urls.py,再结合路由命名name就能快速地从项目应用的urls.py找到某条路由的具体信息,这样就能有效管理整个项目的路由列表。
1、在模板中使用路由
不设置命名空间namespace
# MyDjango的urls.py from django.contrib import admin from django.urls import path, include # 导入Django的路由函数模块 # urlpatterns代表整个项目的路由集合 urlpatterns = [ path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py path('', include('index.urls')), # 指向index的路由文件urls.py ]
# index的urls.py from django.urls import path from . import views urlpatterns = [ # 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。 path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'), path('',views.index) ]
#index的views.py from django.http import HttpResponse from django.shortcuts import render # Create your views here. def mydate(request, year,month,day): return HttpResponse(str(year)+'/'+str(month)+'/'+str(day)) def index(request): return render(request,'index.html')
#templates的index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> hello word! <a href="{% url 'mydate' '2022' '01' '28' %}">查看日期</a> </body> </html>
模板语法url来生成路由地址
{% url 'mydate' '2022' '01' '28' %}中的mydate代表命名为mydate的路由,即index的urls.py设有字符类型、整型和slug的路由。
设置命名空间namespace
# Django的urls.py from django.contrib import admin from django.urls import path, include # 导入Django的路由函数模块 # urlpatterns代表整个项目的路由集合 urlpatterns = [ path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py path('', include('index.urls')), # 指向index的路由文件urls.py path('', include(('index.urls', 'index'), namespace='index')), ]
#templates的index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> hello word! {# <a href="{% url 'mydate' '2022' '01' '28' %}">查看日期</a> #} <a href="{% url 'index:mydate' '2022' '01' '28' %}">查看日期</a> </body> </html>
路由在定义过程中使用命名空间namespace,模板语法url也要添加命名空间。
如:'命名空间namespace:命名路由name'
2、反向解析reverse与resolve
反向解析:用户浏览网站,Django根据网址在路由列表里查找相应的路由,再从路由里找到视图函数或视图类进行处理,将处理结果作为响应内容返回给浏览器并生成网页内容。这是不可逆的,在视图里使用路由则为反向解析。
反向解析由函数reverse和resolve实现。
reverse通过路由命名或可调用视图对象来生成路由地址的;
resolve通过路由地址来获取路由对象信息的。
在使用这两个函数时,需要注意两者所传入的参数类型和返回值的数据类型。
MyDjango的urls.py
from django.contrib import admin from django.urls import path, include # 导入Django的路由函数模块 # urlpatterns代表整个项目的路由集合 urlpatterns = [ path('admin/', admin.site.urls), # 指向内置Admin后台系统的路由文件sites.py path('', include(('index.urls', 'index'), namespace='index')), ]
index的urls.py
from django.urls import path from . import views # 路由命名为index和mydate urlpatterns = [ # 添加带有字符类型、整型和slug的路由。<数据格式类型:变量名>,没有设置数据类型就默认字符类型。 path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'), # 定义首页的路由 path('',views.index,name='index') ]
index的views.py
from django.http import HttpResponse from django.shortcuts import reverse from django.urls import resolve # Create your views here. def mydate(request, year, month, day): args = ['2022', '01', '29'] result = resolve(reverse('index:mydate', args=args)) print('kwargs:', result.kwargs) print('url_name:', result.url_name) print('namespace:', result.namespace) print('view_name:', result.view_name) print('app_name:', result.app_name) return HttpResponse(str(year) + '/' + str(month) + '/' + str(day)) # index主要使用反向解析函数reverse来生成路由mydate的路由地址。 def index(request): kwargs = {'year': 2022, 'month': 2, 'day': 10} args = ['2022', '01', '29'] # 使用reverse生成路由地址 print(reverse('index:mydate', args=args)) print(reverse('index:mydate', kwargs=kwargs)) return HttpResponse(reverse('index:mydate', args=args))
python manage.py runserver
启动服务器后会调用views中index函数
按住ctrl键点击上面的views.py中的reverse,可查看reverse的源码
- viewname:代表路由命名或可调用视图对象,一般情况下是以路由命名name来生成路由地址的。
- urlconf:设置反向解析的URLconf模块。默认情况下,使用配置文件settings.py的ROOT_URLCONF属性(MyDjango文件夹的urls.py)
- args:以列表方式传递路由地址变量,列表元素顺序和数量应与路由地址变量的顺序和数量一致。
- kwargs:以字典方式传递路由地址变量,字典的键必须对应路由地址变量名,字典的键值对数量与变量的数量一致。
- current_app:提示当前正在执行的视图所在的项目应用,主要起到提示作用,在功能上并无实质的作用。
内置的函数方法:
函数方法 | 说明 |
func | 路由的视图函数对象或视图类对象 |
args | 以列表格式获取路由的变量信息 |
kwargs | 以字典格式获取路由的变量信息 |
url_name | 获取路由命名(name) |
app_name | 获取项目路由函数include的参数arg的第二个元素值 |
app_names | 与app_name功能一致,但以列表格式表示 |
namespace | 获取命名空间(namespace) |
namespaces | 与namespace功能一致,但以列表格式表示 |
view_name | 获取整个路由名称,格式:namespace:name |
3、路由重定向
重定向:HTTP协议重定向,也称为网页跳转,就是在浏览器访问某个网页的时候,这个网页不提供响应内容,而是自动跳转到其他网址,由其他网址来生成响应内容。
django的网页重定向有两种方式:第一种方式时路由重定向;第二种方式是自定义视图的重定向。两种重定向方式各有千秋,前者是使用django内置的视图类RedirectView实现的,默认支持HTTP的GET请求;后者是在自定义视图的响应状态设置重定向,能让开发者实现多方面的开发需求。
index的urls.py
from django.urls import path from . import views from django.views.generic import RedirectView urlpatterns = [ # 添加带有字符类型、整型和slug的路由 path('<year>/<int:month>/<slug:day>', views.mydate, name='mydate'), # 定义首页的路由 path('', views.index, name='index'), # 设置路由跳转 path('turnTo', RedirectView.as_view(url='/'), name='turnTo'), ]
在路由里使用视图类RedirectView必须使用as_view方法将视图实例化,参数url用于设置网页跳转的路由地址,“/”表示网站首页(路由命名为index的路由地址),然后在index的view.py定义视图函数mydate和index
index的view.py
from django.http import HttpResponse from django.shortcuts import redirect from django.shortcuts import reverse def mydate(request, year, month, day): return HttpResponse(str(year) + '/' + str(month) + '/' + str(day)) def index(request): print(reverse('index:turnTo')) return redirect(reverse('index:mydate', args=[2019,12,12]))
视图函数index是使用重定向函数redirect实现网页重定向的,函数参数只需传入路由地址即可实现重定向。
模板语法url的参数设置与路由定义是相互关联的,具体说明如下:
- 若路由地址存在变量,则模板语法url需要设置响应的参数值,参数值之间使用空格隔开。
- 若路由地址不存在变量,则模板语法url只需设置路由命名name即可,无须设置额外的参数。
- 若路由地址的变量与模板语法url的参数数量不相同,则在浏览器访问网页的时候会提示NoReverseMatch at的错误信息