• 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.
  • 相关阅读:
    [leetcode]Reverse Words in a String
    *[topcoder]ChooseTheBestOne
    priority_queue c++
    [topcoder]BoxesDiv2
    *[topcoder]IncrementingSequence
    [topcoder]HappyLetterDiv2
    c++ stl 使用汇总(string,vector,map,set)
    2014找工作总结-机会往往留给有准备的人 (转,后台开发面经)
    2015互联网校招总结—一路走来 (移动端开发面经,另有面经汇总)
    通过金矿模型介绍动态规划(转)
  • 原文地址:https://www.cnblogs.com/renpingsheng/p/7764735.html
Copyright © 2020-2023  润新知