Django之反向生成url


首先新建一個項目test_url,項目包含一個名為app01的應用

urls.py文件中生成如下內容

    from django.conf.urls import url
    from django.shortcuts import HttpResponse
    
    def index(request):
    
        return HttpResponse("index")
    
    def test(request):
    
        return HttpResponse("test")
    
    urlpatterns = [
        url(r'^index',index),
        url(r'^test',test),
    ]

啟動項目,用瀏覽器打開http://127.0.0.1:8000/testhttp://127.0.0.1:8000/index/

頁面如下

上面的例子是正向生成url,既然Django可以正向生成url,當然也可以反向生成url

無參數反向生成url

修改urls.py文件

    from django.conf.urls import url
    from django.shortcuts import HttpResponse,redirect
    
    def index(request):
    
        from django.urls import reverse         # 導入reverse
    
        reverse_url=reverse("test_url")         # 用reverse把別名為test_url的路由反向生成url	
        print("reverse_url:",reverse_url)       # 打印反向生成的url
    
        return redirect(reverse_url)            # 重定向到反向生成的url
    
    def test(request):
    
        return HttpResponse("test")
    
    urlpatterns = [
        url(r'^index',index),
        url(r'^test1/test2/test3/test',test,name="test_url"),   # 為test路由設置一個test_url別名
    ]

用瀏覽器打開http://127.0.0.1:8000/index,然后回車

而服務端打印的反向生成的utl如下

可以看到,瀏覽器的地址欄里顯示的url跟我們輸入的地址不一樣,而是跟Django的路由表中設置了路由別名的url是一樣的.

從上面的例子可以看出,反向生成url已經成功了.

有參數的反向生成url

使用正則表達式通過args傳入參數反向生成url

修改urls.py文件

    from django.conf.urls import url
    from django.shortcuts import HttpResponse,redirect
    
    def index(request):
    
        from django.urls import reverse
    
        reverse_url=reverse("test_url",args=(2,8))
        print("reverse_url:",reverse_url)
    
        return redirect(reverse_url)
    
    def test(request,*args,**kwargs):
    
        return HttpResponse("test")
    
    urlpatterns = [
        url(r'^index',index),
        url(r'^test1/(\d+)/test2/test3/(\d+)/test',test,name="test_url"),
    ]

瀏覽器打開http://127.0.0.1:8000/index這個地址

瀏覽器的地址變成了

而在服務端后台打印反向生成的url為

使用正則表達式通過kwargs傳入參數反向生成url

修改urls.py文件

    from django.conf.urls import url
    from django.shortcuts import HttpResponse,redirect
    
    def index(request):
    
        from django.urls import reverse
    
        reverse_url=reverse("test_url",kwargs={"a1":23,"a2":37})
        print("reverse_url:",reverse_url)
    
        return redirect(reverse_url)
    
    def test(request,*args,**kwargs):
    
        return HttpResponse("test")
    
    urlpatterns = [
        url(r'^index',index),
        url(r'^test1/(?P<a1>\d+)/test2/test3/(?P<a2>\d+)/test',test,name="test_url"),
    ]

瀏覽器打開http://127.0.0.1:8000/index這個地址

后台打印反向生成的url

反向生成url之namespace

在上面的例子里,反向生成url使用的是一個視圖函數和一個url別名

再來看反向生成url時,namespace的用法

修改urls.py文件

    from django.conf.urls import url
    from django.shortcuts import HttpResponse,redirect
    
    def index(request):
    
        return HttpResponse("index")
    
    def test(request,*args,**kwargs):
    
        return HttpResponse("test")
    
    urlpatterns = [
        url(r'^app01/',([
            url(r'^index/', index, name="index1"),
            url(r'^test/', test, name="test1"),
        ],"url1","url1")),
    ]

瀏覽器打開http://127.0.0.1:8000/app01/index這個地址

再來反向生成url

	from django.conf.urls import url
	from django.shortcuts import HttpResponse, redirect

	def index(request):
		from django.urls import reverse

		reverse_url=reverse("test1")
		print("reverse_url:",reverse_url)

		return HttpResponse("index")

	def test(request, *args, **kwargs):
		return HttpResponse("test")

	urlpatterns = [
		url(r'^app01/', ([
							url(r'^index/', index, name="index1"),
							url(r'^test/', test, name="test1"),
						], "url1", "url1")),
	]

瀏覽器打開http://127.0.0.1:8000/app01/index這個地址

Django的報錯信息提示:test1不是一個有效的視圖函數或模式的名稱

修改urls.py文件

    from django.conf.urls import url
    from django.shortcuts import HttpResponse, redirect
    
    
    def index(request):
        from django.urls import reverse
    
        reverse_url=reverse("test1")
        print("reverse_url:",reverse_url)
    
        return HttpResponse("index")
    
    def test(request, *args, **kwargs):
        return HttpResponse("test")
    
    urlpatterns = [
        url(r'^app01/', ([
                            url(r'^index/', index, name="index1"),
                            url(r'^test/', test, name="test1"),
                        ], None, None)),
    ]

瀏覽器再次打開http://127.0.0.1:8000/app01/index這個地址

如果url中出現了namespace,必須在reverse方法中加入namespace

urls.py修改,在reverse中加入namespace

    from django.conf.urls import url
    from django.shortcuts import HttpResponse, redirect
    
    def index(request):
        from django.urls import reverse
    
        reverse_url=reverse("url1:test1")
        print("reverse_url:",reverse_url)
    
        return HttpResponse("index")
    
    def test(request, *args, **kwargs):
        return HttpResponse("test")
    
    urlpatterns = [
        url(r'^app01/', ([
                            url(r'^index/', index, name="index1"),
                            url(r'^test/', test, name="test1"),
                        ], "url1", "url1")),
    ]

瀏覽器再次打開http://127.0.0.1:8000/app01/index這個地址

在后台打印加入namespace的反向生成的url

通過博客Django中url的生成過程詳解
知道一個項目的url是可以嵌套多層的,那么多層嵌套url的namespace應該怎么設定呢??

修改urls.py文件的urlpatterns如下

	urlpatterns=[
		url(r'^app01/',([
			url(r'^userinfo/',([
				url(r'^index/',index,name="index1"),
				url(r'^test/',test,name="test1"),
			],None,None))
		],"url1","url1"))
	]

這個url嵌套了3層,最里面一層的url設定了別名,最里面一層的url向外找,應該用誰的namespace呢??

最里面一層的url向外找,中間一層的url的namespace為None,即沒有設定namespace,應該繼續向最外面一層尋找namespace

修改urls.py文件,在reverse方法中添加namespace

    from django.conf.urls import url
    from django.shortcuts import HttpResponse, redirect
    
    def index(request):
        from django.urls import reverse
    
        reverse_url=reverse("url1:test1")
        print("reverse_url:",reverse_url)
    
        return HttpResponse("index")
    
    def test(request, *args, **kwargs):
        return HttpResponse("test")
    
    urlpatterns=[
        url(r'^app01/',([
            url(r'^userinfo/',([
                url(r'^index/',index,name="index1"),
                url(r'^test/',test,name="test1"),
            ],"url2","url2"))
        ],"url1","url1"))
    ]

瀏覽器打開http://127.0.0.1:8000/app01/userinfo/index/地址

如果中間一層也有namespace,這時就有兩個namespace,此時應該用哪個namespace呢??

    from django.conf.urls import url
    from django.shortcuts import HttpResponse, redirect
    
    def index(request):
        from django.urls import reverse
    
        reverse_url=reverse("url2:test1")
        print("reverse_url:",reverse_url)
    
        return HttpResponse("index")
    
    def test(request, *args, **kwargs):
        return HttpResponse("test")
    
    urlpatterns=[
        url(r'^app01/',([
            url(r'^userinfo/',([
                url(r'^index/',index,name="index1"),
                url(r'^test/',test,name="test1"),
            ],"url2","url2"))
        ],"url1","url1"))
    ]

只添加url2這個namespace,刷新瀏覽器頁面

在上面的例子基礎上添加url1這個namespace

    from django.conf.urls import url
    from django.shortcuts import HttpResponse, redirect
    
    def index(request):
        from django.urls import reverse
    
        reverse_url=reverse("url1:url2:test1")
        print("reverse_url:",reverse_url)
    
        return HttpResponse("index")
    
    def test(request, *args, **kwargs):
        return HttpResponse("test")
    
    urlpatterns=[
        url(r'^app01/',([
            url(r'^userinfo/',([
                url(r'^index/',index,name="index1"),
                url(r'^test/',test,name="test1"),
            ],"url2","url2"))
        ],"url1","url1"))
    ]

再次刷新瀏覽器

所以,如果url使用了多層嵌套,且每一層嵌套都有各自的namespace,在使用reverse進行反向生成url的時候

必須要把所有的namespace從最外層向里層使用":"連接起來.

namespace(名稱空間)的作用是什么呢??

  • 當一個項目中有多個應用,每個應用的url都嵌套了多層且里層的url和name別名相同的時候,這時就可以根據namespace來區分不同應用的相同url.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM