第26天,Django之include本质

目录

一、 URL name详解
    向视图传递额外的参数
    利用reverse函数反向生成URL
    对有参数的url设置name
二、include路由转发
    传递额外的参数给include()
三、URL命名空间
四、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'

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339