4.6 路由使用示例讲解
本节将以不同形式的示例演示Django框架下路由的使用情况。
4.6.1 不同方式的路由设置
本节示例用于演示path()、url()、re_path()方法的使用情况,具体操作步骤如下。
1)在Windows系统命令行窗口执行如下命令,建立Django工程demo1。
Django-admin startproject demo1
2)在工程的demo1子文件夹添加视图文件views.py,添加内容如下:
from django.http import HttpResponse def demo1(request): return HttpResponse("hello world") def demo2(request,data): return HttpResponse(data) def demo3(request,x,y): m=int(x)*y return HttpResponse("the product is :" + str(m))
3)修改demo1子文件内路由文件urls.py,修改结果如下:
from django.contrib import admin from django.urls import path,re_path from django.conf.urls import url from .views import * urlpatterns = [ path('admin/', admin.site.urls), path('path/',demo1), re_path(r'^repath\d+/$', demo1), url(r'^url\d+/$', demo1), path('pathA<str:data>/',demo2), re_path(r'^repathA(\d+)/$',demo2), re_path(r'^repathC(?P<data>\d+)/$', demo2), url(r'^urlA(\d+)/$',demo2), url(r'^urlC(?P<data>\d+)/$',demo2), path('pathB<str:x>/',demo3,kwargs = {"y":10}), re_path(r'^repathD(\d+)/$', demo3,kwargs = {"y":10}), re_path(r'^repathB(?P<x>\d+)/$', demo3,kwargs = {"y":10}), url(r'^urlB(?P<x>\d+)/$',demo3,kwargs = {"y":10}), url(r'^urlD(\d+)/$',demo3,kwargs = {"y":10}), path('pathM/', demo3, kwargs={"x":23,"y": 10}), re_path(r'^repathM/$', demo3, kwargs={"x":23,"y": 10}), url(r'^urlM/$', demo3, kwargs={"x":23,"y": 10}), ]
4)在Windows系统命令行窗口,先进入demo1工程文件夹,然后输入如下命令,启动Web服务。
python manage.py runserver
此时打开浏览器,在浏览器地址栏中输入地址127.0.0.1:8000/path/,会出现如图4-1所示的页面。
图4-1 不同方式的路由设置页面浏览1
输入以下四个地址:http://127.0.0.1:8000/repath1/、http://127.0.0.1:8000/repath23/、http://127.0.0.1:8000/url1/、http://127.0.0.1:8000/url23/,均会出现如图4-1所示的结果。
在浏览器地址栏中输入http://127.0.0.1:8000/pathA45/,会出现如图4-2所示的结果。
图4-2 不同方式的路由设置页面浏览2
输入以下四个地址:http://127.0.0.1:8000/repathA45/、http://127.0.0.1:8000/urlA45/、http://127.0.0.1:8000/repathC45/、http://127.0.0.1:8000/urlC45/,均会出现如图4-2所示的结果。
在浏览器地址栏中输入http://127.0.0.1:8000/pathB23/,会出现如图4-3所示的结果。
图4-3 不同方式的路由设置页面浏览3
输入以下四个地址:http://127.0.0.1:8000/repathB23/、http://127.0.0.1:8000/urlB23/、http://127.0.0.1:8000/repathD23/、http://127.0.0.1:8000/urlD23/,均会出现如图4-3所示的结果。
在浏览器地址栏中输入http://127.0.0.1:8000/pathM/,会出现如图4-4所示的结果。
图4-4 不同方式的路由设置页面浏览4
输入http://127.0.0.1:8000/repathM/或http://127.0.0.1:8000/urlM/,出现的界面结果同输入http://127.0.0.1:8000/pathM/时一致。
本例演示了通过path、re_path、url这三种方法设置Django路由的基本情况,并设置了三个视图方法与多个url模型实例。从上述示例可以看出:
1)三个函数值都设置了路由与视图参数,调用演示表明,path()方法的route参数设置相对固定,设置后调用也只有一种url形式,而re_path()、url()这两种方式在设置的regex参数条件满足后,可以以多种url形式调用。
2)通过设置route参数或者regex参数,可以达到通过url进行参数传递的目的。相对而言,path()方法只能采用关键字传参方式,在其设置route传递参数时,必须明确后台调用的视图方法中传递的参数名称;而re_path()、url()可采用位置参数形式传递相关的参数,也可采用关键字参数在regex中进行相应的设置。
3)通过regex设置传递参数,其结果形式为字符串。如将视图方法demo3()调整为如下形式:
def demo3(request,x,y): m= x*y return HttpResponse("the product is :" + str(m))
输入http://127.0.0.1:8000/repathB23/出现的界面如图4-5所示,输入http://127.0.0.1:8000/pathB23/、http://127.0.0.1:8000/urlB23/、http://127.0.0.1:8000/repathD23/、http://127.0.0.1:8000/urlD23/出现的界面结果同输入http://127.0.0.1:8000/pathB23/时一致。
图4-5 不同方式的路由设置页面浏览5
4)path()、re_path()、url()这三种方法都可以通过参数kwargs来设置一个或多个参数,与通过route(或regex)向视图传递数据相比,这种传递形式相对固化,用户在浏览器地址栏中无法干预。
4.6.2 以包含方式调用路由
本节通过示例演示使用include()方法实现路由的情况,具体操作如下:
1)在Windows系统命令行窗口建立Django工程demo2。
Django-admin startproject demo2
2)通过Windows系统命令行窗口进入工程demo2的文件夹,分步执行如下两个操作。
python manage.py startapp app1 python manage.py startapp app2
3)在工程的demo2子文件夹中添加视图文件views.py,添加内容如下:
from django.http import HttpResponse def demo1(request): return HttpResponse("this is demo2 demo1") def demo2(request): return HttpResponse("this is demo2 demo2")
4)在工程的app1子文件夹中修改视图文件views.py,修改结果如下:
from django.http import HttpResponse def demo1(request): return HttpResponse("this is app1 demo1")
5)在工程的app1子文件夹中添加视图文件urls.py,添加内容如下:
from django.urls import path from .views import * urlpatterns = [ path('demo1/', demo1), ]
6)在工程的app2子文件夹中修改视图文件views.py,修改结果如下:
from django.http import HttpResponse def demo1(request,x,y): m=int(x)+int(y) return HttpResponse("this is app2 demo1,result is " + str(m))
7)在工程的app2子文件夹中添加视图文件urls.py,添加内容如下:
from django.urls import path from .views import * urlpatterns = [ path('demo1/', demo1), ]
8)在工程的demo2子文件夹中修改视图文件urls.py,修改结果如下:
from django.contrib import admin from django.urls import path,include from .views import * localpatterns=[ path('demo1/',demo1), path('demo2/',demo2), ] urlpatterns = [ path('admin/', admin.site.urls), path('demo2/',include(localpatterns)), path('app1/', include('app1.urls')), path('app2/<x>/', include('app2.urls'),kwargs={"y":10}), ]
9)在工程的demo2子文件夹中修改视图文件settings.py中的INSTALLED_APPS节点,修改结果如下:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app1', 'app2' ]
10)在Windows系统命令行窗口进入工程demo2的文件夹,然后输入如下命令。
python manage.py runserver
此时打开浏览器,在浏览器地址栏中输入http://127.0.0.1:8000/demo2/demo1/后按回车键,会出现如图4-6所示的页面。
图4-6 路由的包含示例页面浏览1
在浏览器地址栏中输入http://127.0.0.1:8000/demo2/demo2/后按回车键,会出现如图4-7所示的页面。
图4-7 路由的包含示例页面浏览2
在浏览器地址栏中输入http://127.0.0.1:8000/app1/demo1/后按回车键,会出现如图4-8所示的页面。
图4-8 路由的包含示例页面浏览3
在浏览器地址栏中输入http://127.0.0.1:8000/app2/23/demo1/后按回车键,会出现如图4-9所示的页面。
图4-9 路由的包含示例页面浏览4
本例在工程中定义了app1与app2两个应用,同时在已有工程demo2的路由配置文件中定义了localpatterns与urlpatterns两个路由配置集合。从上述示例可以看出:
1)在集合urlpatterns中嵌套调用了localpatterns路由集合,在路由配置集合参数localpatterns中设置了demo2应用的demo1视图方法与demo2视图方法,在实际调用时通过两级路由形式显示。
2)如果使用其他应用模块,需要在主模块的配置文件加载相关应用。
3)在调用app1的路由示例中使用了include()方法加载模块的方式,具体方式为应用名称(默认情况下在应用的apps.py中定义)+应用中路由设置的模块名称。
4)在调用app2的路由示例里,通过route参数、kwargs参数分别传递了两个变量,这种情况下,需要在app2的应用中用所有相关视图方法定义两个变量名称。
4.6.3 路由别名的使用
本示例演示使用include()方法实现路由别名调用的情况,具体操作步骤如下:
1)在Windows系统命令行窗口建立Django工程demo3。
Django-admin startporject demo3
2)通过Windows系统命令行窗口进入工程demo3的文件夹,执行如下操作。
python manage.py startapp app1
3)在工程的demo3子文件夹中添加视图文件views.py,所添加的内容如下:
from django.http import HttpResponse from django.shortcuts import render,redirect,reverse def index(request): return HttpResponse("this is demo3 index") def test1(reqest): return redirect(reverse('index')) def test2(reqest): return redirect(reverse('appspace:index')) def test3(request): return render(request,'template1.html')
4)在工程的app1子文件夹中修改视图文件views.py,代码如下:
from django.http import HttpResponse def index(request): return HttpResponse("this is app1 index")
5)在工程的app1子文件夹中添加视图文件urls.py,所添加的内容如下:
from django.urls import path from .views import * urlpatterns = [ path('index/',index,name="index"), ]
6)在工程的demo3子文件夹中修改视图文件settings.py中的INSTALLED_APPS节点,代码如下:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'demo3', 'app1', ]
7)在工程的demo3子文件夹中添加子文件夹templates,在文件夹内添加template1.html文件,所添加的内容如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo3</title> </head> <body> <h1>this is demo3 test3</h1> <a href="{% url 'index' %} ">跳转</a> </body> </html>
8)在工程的demo3子文件夹中修改视图文件urls.py,代码如下:
from django.contrib import admin from django.urls import path,include from .views import * urlpatterns = [ path('admin/', admin.site.urls), path('index/',index,name="index"), path('test1/',test1), path('test2/',test2), path('test3/',test3), path('app1/',include(('app1.urls','app1'), namespace='appspace')), ]
9)通过Windows系统命令行窗口进入demo3工程文件夹,然后输入如下命令,启动Web服务。
python manage.py runserver
此时打开浏览器,在浏览器地址栏中输入http://127.0.0.1:8000/index/后按回车键,会出现如图4-10所示的页面。
图4-10 路由别名使用示例页面浏览1
再在地址栏输入http://127.0.0.1:8000/test1/后按回车键,会发现地址栏信息变为http://127.0.0.1:8000/index/,出现如图4-11所示的页面。
图4-11 路由别名使用示例页面浏览2
在地址栏输入http://127.0.0.1:8000/test2/后按回车键,会发现地址栏信息变为http://127.0.0.1:8000/app1/index/,出现如图4-12所示的页面。
图4-12 路由别名使用示例页面浏览3
在地址栏输入http://127.0.0.1:8000/test3/后按回车键,出现如图4-13所示的页面。
图4-13 路由别名使用示例页面浏览4
在上述页面中点击“跳转”链接,出现如图4-14所示的页面。
图4-14 路由别名使用示例页面浏览5
本例演示了路由别名的定义及使用情况,从上述示例可以看出:
1)在默认App的url配置文件中,定义了route参数为“url/”的url模型实例,该实例中使用了路由别名参数name,并将其赋值为“index”,用来进行后续的反射调用。
2)route参数为“test1/”的url模型实例在其视图方法test1中使用了路由别名值“index”,并引入了django.shortcuts包内的redirect(),reverse()方法用来做路径反射。
3)本例定义了route参数为“test3/”的url模型实例,用来演示在模板文件中如何使用路径别名进行地址跳转,在模板文件template1.html中使用了标签“url”,同时应用了路由别名值“index”。
4)本例还演示了include方法中命名空间的使用,命名空间的引入是为了避免不同应用中的路由使用了相同的名字而发生冲突,如本例在demo3与app1中均定义了路由别名为“index”的实例,为避免反射调用出错,在实际反射app1中的url实例时,采用了“命名空间名称:路由别名”这种方式调用(appspace:index)。