Django之反向生成url

简介: 首先新建一个项目test_url,项目包含一个名为app01的应用在urls.py文件中生成如下内容 from django.conf.urls import url from django.

首先新建一个项目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/

页面如下

img_7abc092f2de616dc573a55b2a86c1d82.png

img_90ec33d5a4e33a556cddd49c056299fb.png

上面的例子是正向生成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,然后回车

img_45cd5f327696a06f6e1d7616c77adfc9.png

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

img_fd0ab180b4e342174a32b9a7ed330a9a.png

可以看到,浏览器的地址栏里显示的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这个地址

浏览器的地址变成了

img_94bbf58145cb3c91398f9de70f20450d.png

而在服务端后台打印反向生成的url为

img_162f90e6e7082ae220ea075ab6aa1386.png

使用正则表达式通过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这个地址

img_c125d844944cef1493022aedf3d6754b.png

后台打印反向生成的url

img_a717b168a1300e8364f071a697d3b691.png

反向生成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这个地址

img_fdfdf3992716d49a878c1e7cea18a4d7.png

再来反向生成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这个地址

img_f4f68a2c2283b74ffe1c64f2c552e7a1.png

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这个地址

img_4623eaa0c5e0156c19f1efebfa7327d0.png

如果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这个地址

img_846853e41d8b1320309e6800259298a9.png

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

img_dc81a5d1723d22bc97eef4abe1feaf3c.png

通过博客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/地址

img_2ef58da33ea63b573d9566cd0d4aeb6b.png

img_312c11c502ba081232158bdf3224ea0c.png

如果中间一层也有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,刷新浏览器页面

img_95fada1345b2ad2591fcdc2f159a2985.png

在上面的例子基础上添加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"))
    ]
    

再次刷新浏览器

img_b47aa20522b0c7cdcace0f168a252cae.png

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

必须要把所有的namespace从最外层向里层使用":"连接起来.

namespace(名称空间)的作用是什么呢??

  • 当一个项目中有多个应用,每个应用的url都嵌套了多层且里层的url和name别名相同的时候,这时就可以根据namespace来区分不同应用的相同url.
目录
相关文章
|
Python
django url中的正则
django url中的正则
207 0
|
JSON 数据库 数据格式
[Python]Django 视图(View)和URL 与 模板(Template)
[Python]Django 视图(View)和URL 与 模板(Template)
|
网络协议 前端开发 JavaScript
Django第3步_url路由映射与TEMPLATES添加检索路径
Django第3步_url路由映射与TEMPLATES添加检索路径
192 0
|
Python
Django知识点-URL路由 name=
Django知识点-URL路由 name=
162 0
|
JSON 数据格式 Python
django drf 案例--实现url编码和json和dict格式转化小工具(涉及定义模型类,序列化器,类视图,路由),接口测试
django drf 案例--实现url编码和json和dict格式转化小工具(涉及定义模型类,序列化器,类视图,路由),接口测试
|
Python
django restframework,多重排序的url传参写法
django restframework,多重排序的url传参写法
194 0
django restframework,多重排序的url传参写法
|
Python Perl
Django 1.5版:“ url”需要一个非空的第一个参数语法在Django 1.5中已更改
Django 1.5版:“ url”需要一个非空的第一个参数语法在Django 1.5中已更改
260 0
|
Python
获取 Django 项目下全部 URL,一个函数轻松搞定
获取 Django 项目下全部 URL,一个函数轻松搞定
486 0
|
数据库 Python
Django 根据数据库表反向生成Model
Django 根据数据库表反向生成Model
381 0
|
Python
Django中url的生成过程详解
在前面我们知道,Django启动之前会执行admin.py中的autodiscover()方法. def autodiscover(): autodiscover_modules('admin', register_to=site) 在这个方法里,既然autodiscover_modules能执行admin.
872 0