Django命名空间app_name和namespace
在多个app之间,有可能产生同名的url,这个时候避免反转url的时候混淆,可以使用应用命名空间做区分。应用命名空间使用。在应用url中定义 app_name;
一个app,可以创建多个url映射到一个app中,所以就会产生一个问题,在做反转的时候,如果不使用命名空间,就会混淆,为了避免这个问题。我们可以使用实例命名空间。在include函数中添加namespace即可;下面通过两个案例说明
一: 场景1,不同应用中的命名空间(1)新建app应用#python manage.py startapp app01#python manage.py startapp app02
(2)主URL配置
from django.contrib import adminfrom django.conf.urls import url, includefrom django.urls import pathurlpatterns = [ path('admin/', admin.site.urls), path('app01/', include('app01.urls')), path('app02/', include('app02.urls')),]
(2)app01配置 project_django/app01/urls.py
from django.urls import pathfrom . import viewsurlpatterns = [ path('', views.index,name='index'), path('login', views.login,name='login'),]
(3)app01配置 project_django/app01/views.py
from django.http import HttpResponsefrom django.shortcuts import renderfrom django.shortcuts import redirect,reverse# Create your views here.def index(request): if request.GET.get("username"): return HttpResponse("front page app01!") else: return redirect(reverse("login"))def login(request): return HttpResponse("Login page app01!")
(4)app02配置 project_django/app02/urls.py
from django.urls import pathfrom . import viewsurlpatterns = [ path('', views.index,name='index'), path('login', views.login,name='login'),]
(5)app02配置 project_django/app02/views.py
from django.http import HttpResponsefrom django.shortcuts import renderfrom django.shortcuts import redirect, reverse# Create your views here.def index(request): if request.GET.get("username"): return HttpResponse("front page app02!") else: return redirect(reverse("login"))def login(request): return HttpResponse("Login page app02!")
我们可以看到每个app下面的urls都定义了name=index和name=login。 而每个views下面的reverse都是login。这个时候django回去找谁呢? 当我们浏览器打开路径: http://127.0.0.1:8000/app01 的时候,我们会发现跳转异常,竟然跳转到地址: http://127.0.0.1:8000/app02/login 上面。
这个时候我们使用命名空间app_name,就可以很好解决这个问题。
修改配置(1)app01配置 project_django/app01/urls.pyfrom django.urls import pathfrom . import views#命名空间app_name = 'app01' #这里变化了urlpatterns = [ path('', views.index,name='index'), path('login', views.login,name='login'),]
(2)app01配置 project_django/app01/views.py
from django.http import HttpResponsefrom django.shortcuts import renderfrom django.shortcuts import redirect,reverse# Create your views here.def index(request): if request.GET.get("username"): return HttpResponse("front page app01!") else: return redirect(reverse("app01:login")) #这里变化了def login(request): return HttpResponse("Login page app01!")
(3)app02配置 project_django/app02/urls.py
from django.urls import pathfrom . import viewsapp_name = 'app02' #这里变化了urlpatterns = [ path('', views.index,name='index'), path('login', views.login,name='login'),]
(4)app02配置 project_django/app02/views.py
from django.http import HttpResponsefrom django.shortcuts import renderfrom django.shortcuts import redirect, reverse# Create your views here.def index(request): if request.GET.get("username"): return HttpResponse("front page app02!") else: return redirect(reverse("app02:login")) #这里变化了def login(request): return HttpResponse("Login page app02!")
当我们浏览器打开路径: http://127.0.0.1:8000/app01 的时候,就会正常跳转地址: http://127.0.0.1:8000/app01/login 了
二: 场景2,同一个应用中的命名空间先新启一个实例, #python manage.py startapp book1. 我们先看一下代码案例,假设(1)主URL,project_django/project_django/urls.pyfrom django.contrib import adminfrom django.conf.urls import url, includefrom django.urls import pathurlpatterns = [ path('admin/', admin.site.urls), path('book1/', include('book.urls')), path('book2/', include('book.urls')),]
多个url,指向同一个app。
(2)应用book的子URL,project_django/book/urls.pyfrom django.urls import pathfrom . import viewsurlpatterns = [ path('', views.book_list), path('login', views.book_login, name="login"),]
(3)视图,project_django/book/views.py
from django.shortcuts import renderfrom django.http import HttpResponse# Create your views here.from django.shortcuts import redirect,reversedef book_list(request): if request.GET.get("username"): return HttpResponse("My book list !!!!") else: return redirect(reverse("login"))def book_login(request): return HttpResponse("Please Login!!!!")
通过上面案例,我们可以知道。
当执行http://127.0.0.1:8000/book2/ 的时候就会跳转http://127.0.0.1:8000/book2/login
当执行http://127.0.0.1:8000/book1/ 的时候发现还是跳转http://127.0.0.1:8000/book2/login
from django.contrib import adminfrom django.conf.urls import url, includefrom django.urls import pathurlpatterns = [ path('admin/', admin.site.urls), path('book1/', include('book.urls'), namespace='book1')), #变更部分 path('book2/', include('book.urls'), namespace='book2')), #变更部分]
(2)应用book的子URL
from django.urls import pathfrom . import viewsapp_name = "book"urlpatterns = [ path('', views.book_list), path('login', views.book_login, name="login"),]
(3)视图
def book_list(request): #获取当前namespace名称。 current_namespace = request.resolver_match.namespace #变更部分 if request.GET.get("username"): return HttpResponse("My book list !!!!") else: print(current_namespace) #动态返回命名空间信息 return redirect(reverse("%s:login"% current_namespace)) #变更部分def book_login(request): return HttpResponse("Please Login!!!!")
三: include介绍
(1)include(module,namespace=Node)
module:应用app的名称.urlsnamespace:实例命名空间。如果指定实例命名空间,那么必须指定应用命名空间。也就是在应用app的urls.py添加app_name=’xxx‘
如果不加app_name,报错信息:'Specifying a namespace in include() without providing an app_name '
(2)include((pattern_list,app_namesapace),namespace=None)
如果不想在子app中的urls加app_name,那么就可以利用这种方法实现;例子:include(('book.urls','book'),namespace='book')声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。