前言: django命名空間解決什么問題?
-
在多個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 admin from django.conf.urls import url, include from django.urls import path urlpatterns = [ 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 path from . import views urlpatterns = [ path('', views.index,name='index'), path('login', views.login,name='login'), ]
(3)app01配置 project_django/app01/views.py
from django.http import HttpResponse from django.shortcuts import render from 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 path from . import views urlpatterns = [ path('', views.index,name='index'), path('login', views.login,name='login'), ]
(5)app02配置 project_django/app02/views.py
from django.http import HttpResponse from django.shortcuts import render from 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.py
from django.urls import path from . 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 HttpResponse from django.shortcuts import render from 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 path from . import views app_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 HttpResponse from django.shortcuts import render from 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 book
1. 我們先看一下代碼案例,假設
(1)主URL,project_django/project_django/urls.py
from django.contrib import admin from django.conf.urls import url, include from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), path('book1/', include('book.urls')), path('book2/', include('book.urls')), ]
多個url,指向同一個app。
(2)應用book的子URL,project_django/book/urls.py
from django.urls import path from . import views urlpatterns = [ path('', views.book_list), path('login', views.book_login, name="login"), ]
(3)視圖,project_django/book/views.py
from django.shortcuts import render from django.http import HttpResponse # Create your views here. from django.shortcuts import redirect,reverse def 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
這不是我們想要的結果,我們希望訪問/book1/的時候跳轉/book1/login;訪問/book2/的時候跳轉/book2/login; 那么通一個應用中的兩個實例,我們如何區分?
2. 案例修改
(1)主URL
from django.contrib import admin from django.conf.urls import url, include from django.urls import path urlpatterns = [ 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 path from . import views app_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!!!!")
原文鏈接:https://blog.51cto.com/jiajinh/2432449