• Django之include本质


    一、 URL name详解

    from django.conf.urls import url
    from django.contrib import admin
    from calc import views as calc_views
     
     
    urlpatterns = [
        url(r'^add/$', calc_views.add, name='add'),
        url(r'^add/(d+)/(d+)/$', calc_views.add2, name='add2'),
        url(r'^admin/', admin.site.urls),
    ]
    

    url(r'^add/$', calc_views.add, name='add'), 这里的 name='add' 是用来干什么的呢?

    简单说,name 可以用于在 templates, models, views ……中得到对应的网址,相当于“给网址取了个名字”,只要这个名字不变,网址变了也能通过名字获取到。

    模板中可以这样利用name

    不带参数的:
    {% url 'name' %}
    
    带参数的:参数可以是变量名
    {% url 'name' 参数 %}

    结合上面的urls.py

    不带参数:
    <a href="{% url 'add' %}">添加</a>
    
    上面模板经过渲染后的标签是这样的:
    <a href="/add/">添加</a>
    
    
    带参数的:
    <a href="{% url 'add2' 4 5 %}">link</a>
    
    经过渲染后:
    <a href="/add/4/5/">link</a>
    

    当 urls.py 进行更改,前提是不改 name(这个参数设定好后不要轻易改),获取的网址也会动态地跟着变,比如改成:

    url(r'^new_add/(d+)/(d+)/$', calc_views.add2, name='add2'),
    

    注意: add 变成了 new_add,但是后面的 name='add2'没改,这时 {% url 'add2' 4 5 %} 就会渲染对应的网址成/new_add/4/5/

    向视图传递额外的参数

    url()中允许你传递一个Python字典作为额外的关键字参数给视图函数。

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
    ]
    

    在上面的例子中,对于/blog/2005/请求,Django将调用views.year_archive(request, year='2005', foo='bar')。

    注意:命名关键字参数和在字典中传递的额外参数要避免重名。

    利用reverse函数反向生成URL

    urls.py

    from app01 import views as views
    
    urlpatterns = [
        url(r'^login/',views.login),
        url(r'^index/first/',views.index,name='first'),
    ]
    

    views.py

    from django.shortcuts import render,HttpResponse,redirect
    from django.urls import reverse
    
    def login(request):
        url = reverse('first')
        print(url)  # 打印结果:/index/first/
        return redirect(url)
    
    
    def index(request):
        return HttpResponse('index/first')
    

    对有参数的url设置name

    urls.py:

    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        #...
        url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
        #...
    ]
    

    模板代码中使用:

    <a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>   # 注意模版语言的用法,注意参数的传递方法
    {# Or with the year in a template context variable: #}
    <ul>
    {% for yearvar in year_list %}
    <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
    {% endfor %}
    </ul>
    

    views.py视图函数:

    from django.urls import reverse
    from django.http import HttpResponseRedirect
    
    def redirect_to_year(request):
        # ...
        year = 2006
        # ...注意参数的传递方法
        return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
    

    二、include路由转发

    通常,我们会在每个app里,各自创建一个urls.py路由模块,然后从根路由出发,将app所属的url请求,全部转发到相应的urls.py模块中。

    创建两个app:cmdb和openstack,并分别在这两个app目录下创建urls.py文件

    from django.conf.urls import url,include    
        # 需要先导入include函数
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^cmdb/',include('cmdb.urls')),
        url(r'^openstack/',include('openstack.urls')),
    ]
    

    传递额外的参数给include()

    参数会传递给include指向的urlconf中的每一行,例如,下面两种URLconf配置方式在功能上完全相同:

    配置一:

    # main.py
    from django.conf.urls import include, url
    
    urlpatterns = [
        url(r'^blog/', include('inner'), {'blogid': 3}),
    ]
    
    # inner.py
    from django.conf.urls import url
    from mysite import views
    
    urlpatterns = [
        url(r'^archive/$', views.archive),
        url(r'^about/$', views.about),
    ]
    

    配置二:

    # main.py
    from django.conf.urls import include, url
    from mysite import views
    
    urlpatterns = [
        url(r'^blog/', include('inner')),
    ]
    
    # inner.py
    from django.conf.urls import url
    
    urlpatterns = [
        url(r'^archive/$', views.archive, {'blogid': 3}),
        url(r'^about/$', views.about, {'blogid': 3}),
    ]
    

    注意,只有当你确定被include的URLconf中的每个视图都接收你传递给它们的额外的参数时才有意义,否则其中一个以上视图不接收该参数都将导致错误异常。

    三、URL命名空间

    URL命名空间可以保证反查到唯一的URL。

    urls.py

    from django.conf.urls import url,include
    
    urlpatterns = [
        url(r'^cmdb/',include('cmdb.urls',namespace='cmdb')),
        url(r'^openstack/',include('openstack.urls',namespace='openstack')),
    ]
    

    cmdb/urls.py

    from django.conf.urls import url
    from cmdb import views
    
    urlpatterns = [
        url(r'host/',views.host,name='host'),
    ]
    

    在模板中使用

    <a href="{% url 'cmdb:host' %}">跳转</a>
    

    在视图中利用reverse()函数反向生成url

    from django.shortcuts import render,HttpResponse,redirect
    from django.urls import reverse
    def host(request):
        url = reverse('cmdb:host')
        print(url)      # 打印结果:/cmdb/host/
        return HttpResponse('cmdb.host')
    

    注意:namespace与name在模板文件和视图函数中使用的时候要用冒号分隔,如:“cmdb:host”

    四、include()本质

    include()函数实际上就是返回一个元组:([], None, None)
    第一个元素可以是一个列表,列表中盛放url()子路由配置;
    第二个元素是app_name,可以为None;
    第三个元素是namespace,需要反向生成url时,可根据需求填写;

    所以urls.py也可以这样写:

    from django.conf.urls import url
    
    urlpatterns = [
        url(r'^openstack/',([],None,None,),
    ]
    

    直接用一个元组替代include()

    如下,直接进行子路由分发:

    from django.conf.urls import url,include
    from cmdb import views as cviews
    from app01 import views
    
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^index/',views.index,name='index'),
        url(r'^cmdb/',include('cmdb.urls',namespace='cmdb')),
        # url(r'^openstack/',include('openstack.urls',namespace='openstack')),
        url(r'^openstack/',([
            url(r'^host/',cviews.host,name='host'),
            url(r'^host/add/',cviews.addhost,name='addhost'),
            url(r'^host/(d+)/change',cviews.changehost,name='changehost'),
        ],None,'openstack')),
    ]
    

    以上元组中的'openstack',就相当于include()函数的namespace='openstack'



    作者:天佑俊辰
    链接:https://www.jianshu.com/p/0e5bdc73fcab
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    python中list常用的方法
    python登陆代码简单逻辑
    学习Python前言
    Python远程连接Redis
    virtualbox虚拟机之连接本地主机同时可以连接外部网络
    Redis统计访问量方法
    Linux:less and Aix:more
    python之class Meta用法
    pycharm之ctrl+鼠标滚轮调整字体大小
    python之cookie与session
  • 原文地址:https://www.cnblogs.com/ellisonzhang/p/10612676.html
Copyright © 2020-2023  润新知