路由分发下反向解析遇到不同路由相同name属性值的问题处理
路由分发下反向解析遇到不同路由相同name属性值的问题处理
准备工作
首先,我们新建一个名为NameSpace的Django项目,然后在里面创建两个应用,分别叫customer与payment,记得在settings中的INSTALLED_APPS中注册这两个应用~
接着,在template目录中分别创建两个项目的模板文件夹~而且让其中的两个网页名字一样,项目的具体结构如下:
路由分发
全局的urls文件中(跟项目名同名的目录里的文件我习惯叫全局文件)做路由分发:
urlpatterns = [ path('admin/', admin.site.urls), re_path('^customer/',include('customer.urls')), re_path('^payment/',include('payment.urls')), ]
customer目录中新建的urls文件
from django.urls import path,re_path from customer import views urlpatterns = [ re_path(r'^index/$',views.index,name='index'), ]
payment目录中新建的urls文件
from django.urls import path,re_path from payment import views urlpatterns = [ re_path(r'^index/$',views.index,name='index'), ]
视图函数
customer目录中的视图函数
from django.shortcuts import render,HttpResponse from django.urls import reverse def index(request): if request.method == 'GET': url = reverse('index') print('customer_url:',url) return HttpResponse(url)
payment目录中的视图函数
from django.shortcuts import render,HttpResponse from django.urls import reverse def index(request): if request.method == 'GET': url = reverse('index') print('payment:',url) return HttpResponse(url)
存在问题
大家可以看到:我在两个应用的分发路由中给两个不同的index路径(事实上,我们访问customer的indexs的路径其实是/customer/index/,同理payment的index的路径是/payment/index/)取了相同的别名index;而且在不同的视图函数中通过反向解析拿到了别名index对应的路径打印了出来并返回给浏览器。
现在我们试试实际的运行效果:
当我访问payment的index的时候确实打印出了正确的路径:
但是,当我访问customer的路径的时候出错了:这个url竟然被反向解析成了payment的index路径!
让我们再来看看后台打印的效果:从第二条数据可以看出来~浏览器明明收到的是customer的get请求,可是反向解析出来的index的路径却是另外一条路由!
实际中这样出现这样的问题是十分危险的!为了避免这种情况发生,可以利用名称空间解决~
名称空间解决
利用名称空间可以解决上面的问题~
首先我们在路由分发的时候为每条分发的路由加上名称空间:
urlpatterns = [ path('admin/', admin.site.urls), re_path('^customer/',include(('customer.urls','customer'))), re_path('^payment/',include(('payment.urls','payment'))), ]
两个应用的分发的路由中的写法还跟上面的一样~
在视图函数中进行反向解析的时候为每个别名加上自己的名称空间~
customer的视图函数:
from django.shortcuts import render,HttpResponse from django.urls import reverse def index(request): if request.method == 'GET': url = reverse('customer:index') print('customer_url:',url) return HttpResponse(url)
payment的视图函数:
from django.shortcuts import render,HttpResponse from django.urls import reverse def index(request): if request.method == 'GET': url = reverse('payment:index') print('payment:',url) return HttpResponse(url)
最后让我们看看结果:
(1)访问payment的结果:
(2)访问customer的结果:
(3)最后看看打印结果:
所以~实际开发中名称空间不能重名!