Django反向解析(下)
一 应用命名空间app_name
1.1 在app02/urls.py 中添加app_name 信息
from django.urls import path, re_path
from . import views
app_name = "ns_app02" #添加这行
urlpatterns = [
re_path('test111/([0-9]{2})/$', views.test, name="app_02"),
]
1.2 在视图中使用应用命名空间
编辑app01/views.py 中添加信息
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect,reverse
# Create your views here.
from django.http import HttpResponseRedirect
from django.urls import reverse
def test(request):
return HttpResponseRedirect(reverse("ns_app02:app_02",args=(11,)))
1.3 测试访问
访问app1/test/地址
完成测试。
二 实例命名空间namespace
一个APP,在运行的时候多个实例。
例如:假设一个APP,实现一个index页面展示功能。
- 假设访问Django服务器的人分两类,author和publisher,作者和出版社
- 他们都需要访问app
- 业务需求:为两类人实现不同的权限或者页面内容
- 尽可能重用代码
为此,我们可以这么实现:
- 根据不同的URL来区分人,author访问author/,publisher访问publisher/ 。
- 两个URL都指向同一个APP的URL:include(APP/URLS)。
- 在APP的视图中,用IF/ELSE 判断APP_NAMESPACE的名字来区分不同的访问人员,实现不同的返回页面的逻辑。
- 这样,我们就相当于用一个APP下的URL和VIEWS实现了两套APP,这就是所谓的APP多实例。
注意:
- namespace定义在include中。
- 整个项目的所有app中的所有namespace不能重名,也就是全局唯一。
- 使用namespace功能的前提是设置
app_name
,如果不设置,会弹出异常。 - 要在视图中获取namespace属性值,通过
request.resolver_match.namespace。
正向解析代码示例配置
主URL
from django.contrib import admin
from django.urls import path,include,re_path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
#一个app多个实例,namespaces区分示例
path("author/", include("app01.urls", namespace='app01_space_author')), #appname_spacename的格式
path("publisher/", include("app01.urls", namespace="app01_space_publisher")),
APP URL 配置(APP这里名字为app01)
from django.urls import path, re_path
from . import views
app_name = 'app01' #这行必须要
urlpatterns = [
#一个app多个实例,namespaces区分示例
re_path('index/$', views.index, name="index"),
re_path('detail/$', views.detail, name="detail"),
]
APP VIEWS配置
from django.shortcuts import render,HttpResponse
def index(request):
return HttpResponse('当前命名空间是:%s'% request.resolver_match.namespace)
def detail(request):
if request.resolver_match.namespace == 'app01_space_author':
return HttpResponse('这里是作者的页面')
elif request.resolver_match.namespace == 'app01_space_publisher':
return HttpResponse('这里是出版商的页面')
else:
return HttpResponse('默认返回页面')
反向解析代码示例
主URL
from django.contrib import admin
from django.urls import path,include,re_path
# from app01 import urls
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
#一个app多个实例,namespaces区分示例
path("author/", include("app01.urls", namespace='app01_space_author')),
path("publisher/", include("app01.urls", namespace="app01_space_publisher")),
#反向解析
path('goto/', views.goto),
]
主views.py
from django.http import HttpResponseRedirect
from django.urls import reverse
#测试跳转
def goto(request):
print(reverse('app01:index'))
return HttpResponseRedirect(reverse('app01:detail')) #跳转到解析的地址,地址为app01这个appname下的detail这个别名url
app01/urls.py
from django.urls import path, re_path
from . import views
app_name = 'app01' #这行必须要
urlpatterns = [
#一个app多个实例,namespaces区分示例
re_path('index/$', views.index, name="index"),
re_path('detail/$', views.detail, name="detail"),
]
app01/views.py
from django.shortcuts import render,HttpResponse,HttpResponseRedirect,reverse
def index(request):
return HttpResponse('当前命名空间是:%s'% request.resolver_match.namespace)
def detail(request):
print(request.resolver_match.namespace) #打印当前请求URL的namespace信息
if request.resolver_match.namespace == 'app01_space_author':
return HttpResponse('这里是作者的页面')
elif request.resolver_match.namespace == 'app01_space_publisher':
return HttpResponse('这里是出版商的页面')
else:
return HttpResponse('默认返回页面')
运行测试
访问
查看命令
Starting development server at http://0.0.0.0:8000/
Quit the server with CTRL-BREAK.
Not Found: /
[03/Aug/2021 15:03:21] "GET / HTTP/1.1" 404 2242
[03/Aug/2021 15:03:24] "GET /goto HTTP/1.1" 301 0
/publisher/index/ #这里是(print(request.resolver_match.namespace) 打印的信息)
[03/Aug/2021 15:03:24] "GET /goto/ HTTP/1.1" 302 0
app01_space_publisher
[03/Aug/2021 15:03:24] "GET /publisher/detail/ HTTP/1.1" 200 27
如果在模板中使用呢?
主目录的urls
from django.contrib import admin
from django.urls import path,include,re_path
# from app01 import urls
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
#一个app多个实例,namespaces区分示例
path("author/", include("app01.urls", namespace='app01_space_author')),
path("publisher/", include("app01.urls", namespace="app01_space_publisher")),
re_path('page/$', views.page), #定义一个page测试页面
app01/urls.py
from django.urls import path, re_path
from . import views
app_name = 'app01' #这行必须要
urlpatterns = [
#一个app多个实例,namespaces区分示例
re_path('index/$', views.index, name="index"),
re_path('detail/$', views.detail, name="detail"),
]
app01/views.py
from django.shortcuts import render,HttpResponse,HttpResponseRedirect,reverse
def index(request):
return HttpResponse('当前命名空间是:%s'% request.resolver_match.namespace)
def detail(request):
print(request.resolver_match.namespace)
if request.resolver_match.namespace == 'app01_space_author':
return HttpResponse('这里是作者的页面')
elif request.resolver_match.namespace == 'app01_space_publisher':
return HttpResponse('这里是出版商的页面')
else:
return HttpResponse('默认返回页面')
templates/test,html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test direct test</title>
</head>
<body>
<p><a href="{% url 'app01:index' %}">app示例,无法区分多个实例</a></p>
<p><a href="{% url 'app01_space_author:index' %}">多实例ns区分,这里是author首页</a></p>
<p><a href="{% url 'app01_space_publisher:index' %}">多实例ns区分,这里是publisher首页</a></p>
</body>
</html>
启动项目
访问 http://localhost:8000/page/
演示完毕
本文参考江哥博客内容例子
如有错误麻烦指正,多谢!