被解放的姜戈03 所谓伊人

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

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

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

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

模板初体验

我们拿一个独立的templay.html文件作为模板。它放在templates/west/文件夹下。文件系统的结构现在是:

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

templay.html文件的内容是:

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

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

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

# 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。

“勇士穿过地狱火焰,因为,她值得。”

总结

使用模板实现视图分离。

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C/C++基础

Google C++编程风格指南(一)之头文件的相关规范

一个良好的编程规范和风格是一名程序猿成熟的标志。规范的编码可以减少代码冗余,降低出错概率,便于代码管理和代码交流等等,事实上,其作用远不止这些,我们要牢记编码规...

17710
来自专栏GopherCoder

『Go 内置库第一季:net/url』

其实这是一个比较小的内置函数,主要用在网络请求方面上,可能最多的用途也就是用来处理网络请求的参数。当然如何你经常在项目中编写restfulAPI, 那么你也可能...

16120
来自专栏腾讯移动品质中心TMQ的专栏

手机APP安装包缩减方案

安装包大小对于产品很重要 主要有如下几个原因: 1、手机APP安装包的大小会影响用户是否愿意花费流量来下载此APP; 2、包体越大下载过程越长,用户取消下载的可...

31560
来自专栏Android小菜鸡

NativeJS理解和使用

  Native.js技术,简称NJS,是一种将手机操作系统的原生对象转义,映射为JS对象,在JS里编写原生代码的技术。   如果说Node.js把js扩展到...

98450
来自专栏程序员的知识天地

使用 JS 实现一个本地数据库

前端很多时候还是需要保存一些数据的,这里的保存指的是长久的保存。以前的思想是把数据保存在 Cookie 中,或者将 key 保存在 Cookie 中,将其他数据...

46720
来自专栏Golang语言社区

Go语言并发与并行学习笔记

Go语言的并发和并行 不知道你有没有注意到一个现象,还是这段代码,如果我跑在两个goroutines里面的话: var quit chan int = make...

32560
来自专栏Java Web

Java 面试知识点解析(二)——高并发编程篇

在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Jav...

54470
来自专栏PHP实战技术

PHP经典面试题目汇总(上篇)

1、双引号和单引号的区别 双引号解释变量,单引号不解释变量 双引号里插入单引号,其中单引号里如果有变量的话,变量解释 双引号的变量名后面必须要有一个非数字、字母...

37270
来自专栏FreeBuf

一个二进制POC的诞生之旅CVE-2018-0802

背景 在潜伏17年的“噩梦公式”漏洞(CVE-2017-11882)被曝光修补之后,之前的漏洞程序EQNEDT32.EXE在windows 10系统下仍然没有开...

29490
来自专栏前端达人

JavaScript基础——你真的清楚JavaScript是什么吗?

为前端开发,你是否问过自己或者思考过什么是JavaScript吗?JavaScript有什么特点?如果让你让一句话高度介绍,你会怎么说?小编认为,在你想深入一门...

278100

扫码关注云+社区

领取腾讯云代金券