(3)正则路径——有名分组
- 使用正则路径时,模板中利用
{% url "别名" 分组名=符合正则匹配的参数 %}
来实现反向解析,多个分组,使用空格
分割 - urls.py文件
#-*- coding: utf-8 -*- from operator import indexOf from django.urls import path,re_path from . import views urlpatterns = [ path('index/',views.index), re_path('^login/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.login,name="login"), #别名login ]
- views.py文件
# -*- coding: utf-8 -*- from django.urls import reverse from django.http import HttpResponse from django.shortcuts import redirect,render from django.views.decorators.csrf import csrf_exempt def index(request): return render(request,"test.html") @csrf_exempt def login(request,year,month): #添加新参数 username = request.POST.get('username') pwd = request.POST.get('pwd') if username == "zhangsan" and pwd == "123456": return HttpResponse("登录成功,当前年份:" + year + "月份" + month) else: return HttpResponse("登录失败,当前年份:" + year + "月份" + month)
- templates/test.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>用户登录</h3> <form action="{% url 'login' year='2022' month='09' %}" method="post"> {% csrf_token %} <p>用户名:<input type="text" name="username"></p> <p>密码:<input type="text" name="pwd"></p> <input type="submit"> </form> </body> </html>
- 访问
127.0.0.1:8000/index/
,使用正确的username
和pwd
,查看终端输出,然后使用错误的参数进行访问
五、命名空间
命名空间(namespace),表示标识符的可见范围,一个标识符可以在多个命名空间定义,不同命名空间的标识符含义不会相干
一个新的命名空间可以定义任意标识符,并且不会与其他命名空间的相同标识符发生冲突
使用原因:
路由别名没有作用域,而Django在反向解析URL时会进行全局搜索,搜索到的第一个路由别名,会直接返回,当在不同app目录下定义相同的路由别名时,可能会导致反向解析错误,而命名空间就可以解决这个问题
在helloworld同等目录下创建test1和test2,并且分别在两个目录下创建urls.py和views.py
编写两个目录的urls.py和views.py
- test1的urls.py #-*- coding: utf-8 -*- from django.urls import path from . import views urlpatterns = [ path('index1/',views.test1), ] - test1的views.py # -*- coding: utf-8 -*- from django.http import HttpResponse def test1(request): return HttpResponse("Test1") - test2的urls.py #-*- coding: utf-8 -*- from django.urls import path from . import views urlpatterns = [ path('index2/',views.test2), ] - test2的views.py # -*- coding: utf-8 -*- from django.http import HttpResponse def test2(request): return HttpResponse("Test2")
- 修改
helloworld/urls.py
,这个是主app
#-*- coding: utf-8 -*- from django.urls import path,include #导入include #from . import views urlpatterns = [ path('test1/',include("test1.urls")), #导入两个app path('test2/',include("test2.urls")), ]
include参数直接传一个元组,元组的第一个参数是指定APP的urls
,第二个参数是指定命名空间
- 现在分别访问
127.0.0.1:8000/test1/index1
和127.0.0.1:8000/test2/index2
- 已经可以成功访问,现在为两个app的urls都加上别名,名称都是
index
- test1的urls.py #-*- coding: utf-8 -*- from django.urls import path from . import views urlpatterns = [ path('index1/',views.test1,name='index'), ] - test2的urls.py #-*- coding: utf-8 -*- from django.urls import path from . import views urlpatterns = [ path('index2/',views.test2,name='index'), ]
- 修改两个app的views.py,设置反向解析,都重定向到
index
- test1的views.py # -*- coding: utf-8 -*- from django.http import HttpResponse from django.urls import reverse def test1(request): return HttpResponse(reverse('index')) #输出reverse('index')会返回反向解析的资源路径 - test2的views.py # -*- coding: utf-8 -*- from django.http import HttpResponse from django.urls import reverse def test2(request): return HttpResponse(reverse('index'))
- 这样配置之后,我们想要达到的目的访问不同的app时,都可以返回自己相应的资源路径,现在来访问观察效果
可以发现访问两个资源,返回的都是test2/index2也就是test2的资源路径,这样肯定是不符合需求的,现在来加上命名空间
造成这样的结果,是因为别名是没有作用域的,所以在django反向解析时,会在项目全局顺序搜索,当查找到第一个时,就会直接返回
修改两个app的urls
- test1的urls.py #-*- coding: utf-8 -*- from django.urls import path from . import views app_name = 'test1' #设置命名空间名称 urlpatterns = [ path('index1/',views.test1,name='index'), ] - test2的urls.py #-*- coding: utf-8 -*- from django.urls import path from . import views app_name = 'test2' urlpatterns = [ path('index2/',views.test2,name='index'), ]
- 修改
helloworld/urls.py
#-*- coding: utf-8 -*- from django.urls import path,include #from . import views urlpatterns = [ path('test1/',include("test1.urls",namespace='test1')), #指定命名空间 path('test2/',include("test2.urls",namespace='test2')), ]
- 修改两个app的
views.py
- test1的views.py # -*- coding: utf-8 -*- from django.http import HttpResponse from django.urls import reverse def test1(request): return HttpResponse(reverse('test1:index')) #test1表示命名空间,index表示别名 - test2的views.py # -*- coding: utf-8 -*- from django.http import HttpResponse from django.urls import reverse def test2(request): return HttpResponse(reverse('test2:index'))
现在再来访问
- 成功达到的目的!!!
- 模板使用命名空间和使用reverse相似,同样也是在指定别名时,前面添加命名空间名称,例如:
{% url '命名空间名称:别名' %}