1 2 3

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/  

    

 

     演示完毕

   

 

本文参考江哥博客内容例子

 

如有错误麻烦指正,多谢!

posted @ 2021-08-03 11:29  矜持小蝌蚪  阅读(104)  评论(0编辑  收藏  举报
levels of contents