被解放的姜戈03 所谓伊人

被解放的姜戈03 所谓伊人html

 

做者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!数据库

 

在以前的程序中,咱们直接生成一个字符串,做为http回复,返回给客户端。这一过程当中使用了django.http.HttpResponse()。django

在这样的一种回复生成过程当中,咱们实际上将数据和视图的格式混合了到上面的字符串中。看似方便,却为咱们的管理带来困难。想像一个成熟的网站,其显示格式会有许多重复的地方。若是能够把数据和视图格式分离,就能够重复使用同一视图格式了。编程

Django中自带的模板系统,能够将视图格式分离出来,做为模板使用。这样,不但视图能够容易修改,程序也会显得美观大方。post

“她是我心中最美的人”,姜戈对德国人说。网站

 

模板初体验

咱们拿一个独立的templay.html文件做为模板。它放在templates/west/文件夹下。文件系统的结构如今是:this

mysite/
├── mysite
├── templates
│   └── west
└── west

 

templay.html文件的内容是:url

<h1>{{ label }}</h1>

能够看到,这个文件中,有一个奇怪的双括号包起来的陌生人。这就是咱们将来数据要出现的地方。而相关的格式控制,即<h1>标签,则已经标明在该模板文件中。spa

 

咱们须要向Django说明模板文件的搜索路径,修改mysite/settings.py,添加:code

# Template dir TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates/west/'), )

若是还有其它的路径用于存放模板,能够增长该元组中的元素,以便Django能够找到须要的模板。

 

咱们如今修改west/views.py,增长一个新的对象,用于向模板提交数据:

复制代码
# -*- coding: utf-8 -*- #from django.http import HttpResponse from django.shortcuts import render def templay(request): context = {} context['label'] = 'Hello World!' return render(request, 'templay.html', context)
复制代码

能够看到,咱们这里使用render来替代以前使用的HttpResponse。render还使用了一个词典context做为参数。这就是咱们的数据。

context中元素的键值为'label',正对应刚才的“陌生人”的名字。这样,该context中的‘label’元素值,就会填上模板里的坑,构成一个完整的http回复。

 

做为上节内容的一个小练习,自行修改west/urls.py,让http://127.0.0.1:8000/west/templay的URL请求能够找到相应的view对象。

 

访问http://127.0.0.1:8000/west/templay,能够看到页面:

 

“我给你讲个故事吧,勇士拯救公主的故事”,德国人说。

 

流程

再来回顾一下整个流程。west/views.py中的templay()在返回时,将环境数据context传递给模板templay.html。Django根据context元素中的键值,将相应数据放入到模板中的对应位置,生成最终的http回复。

这一模板系统能够与Django的其它功能相互合做。上一回,咱们从数据库中提取出了数据。若是将数据库中的数据放入到context中,那么就能够将数据库中的数据传送到模板。

修改上次的west/views.py中的staff:

def staff(request): staff_list = Character.objects.all() staff_str = map(str, staff_list) context = {'label': ' '.join(staff_str)} return render(request, 'templay.html', context)

 

练习: 显示上面的staff页面。

 

“勇士翻太高山,并不是由于他不惧怕。”

 

循环与选择

Django实际上提供了丰富的模板语言,能够在模板内部有限度的编程,从而更方便的编写视图和传送数据。

咱们下面体验一下最多见的循环与选择。

 

上面的staff中的数据其实是一个数据容器,有三个元素。刚才咱们将三个元素链接成一个字符串传送。

实际上,利用模板语言,咱们能够直接传送数据容器自己,再循环显示。修改staff()为:

def staff(request): staff_list = Character.objects.all() return render(request, 'templay.html', {'staffs': staff_list})

从数据库中查询到的三个对象都在staff_list中。咱们直接将staff_list传送给模板。

将模板templay.html修改成:

{% for item in staffs %} <p>{{ item.id }}, {{item}}</p> {% endfor %}

咱们以相似于Python中for循环的方式来定义模板中的for,以显示staffs中的每一个元素。

还能够看到,对象.属性名的引用方式能够直接用于模板中。

 

选择结构也与Python相似。根据传送来的数据是否为True,Django选择是否显示。使用方式以下:

复制代码
{% if condition1 %}
   ... display 1
{% elif condiiton2 %}
   ... display 2
{% else %}
   ... display 3
{% endif %}
复制代码

其中的elif和else和Python中同样,是能够省略的。

 

“勇士屠杀恶龙,并不是由于他不恐惧。”

 

模板继承

模板能够用继承的方式来实现复用。咱们下面用templay.html来继承base.html。这样,咱们可使用base.html的主体,只替换掉特定的部分。

新建templates/west/base.html:

复制代码
<html> <head> <title>templay</title> </head> <body> <h1>come from base.html</h1> {% block mainbody %} <p>original</p> {% endblock %} </body> </html>
复制代码

该页面中,名为mainbody的block标签是能够被继承者们替换掉的部分。

 

咱们在下面的templay.html中继承base.html,并替换特定block:

复制代码
{% extends "base.html" %} {% block mainbody %} {% for item in staffs %} <p>{{ item.id }},{{ item.name }}</p> {% endfor %} {% endblock %}
复制代码

第一句说明templay.html继承自base.html。能够看到,这里相同名字的block标签用以替换base.html的相应block。

 

“勇士穿过地狱火焰,由于,她值得。”

 

总结

使用模板实现视图分离。

数据传递,模板变量,模板循环与选择,模板继承。

 

姜戈静静的说,“我懂得他的感觉。”

 

欢迎阅读“被解放的姜戈”系列文章。

相关文章
相关标签/搜索