Template tags
Template tags
在先前的 Templates 章节中,我们已经学会基础的 Django Template 用法 (在 Template 裡呈现变数内容)。但为了产生完整的网页,我们会需要能在 Template 裡执行一些简单的 Python 语法,例如:
- 逻辑判断 (if else) -- 若使用者己经登入,则显示使用者的暱称;若未登入,则显示登入按钮
- 重覆 HTML 片段 (for loop) -- 列出所有好友的ID 和显示图片
- 格式化 Template 中的变数 -- 例如日期的格式化
因为我们 Django template tags 让你可以在 HTML 档案裡使用类似 Python 的语法,动态存取 View 传过来的变数,或是在显示到浏览器之前帮你做简单的资料判断、转换、计算等等。
在这一章,我们将到使用 Django ORM 存取资料库 ,捞出旅游日记全部的 Post 传入 Template。并使用 Django 的 Template Tag 、Template Filter 一步步产生旅游日记的首页。
建立旅游日记的首页
确认首页需求
在开始动工之前,我们先确认需求。
旅游日记的首页应该会有:
- 标题
- 照片
- 发佈日期
- 部份的游记内文
建立首页的 View
首先,我们先建立一个新的 View function - home()
:
# trips/views.py
from django.shortcuts import render
from trips.models import Post
def home(request):
# get all the posts
post_list = Post.objects.all()
return render(request,
'home.html',
{'post_list': post_list})
- 汇入所需的 Model -- 记得 import 需要用到的 Model
Post
- 取得所有Post -- 透过
Post.objects.all()
,从资料库取得全部的 post ,并回传至home.html
这个 template。
设定首页的 Url
接下来,我们修改 urls.py ,将首页 ( 正规表达式^$
) 指向 home() 这个 View function:
# mysite/urls.py
from trips.views import hello_world, home
urlpatterns = patterns('',
...
url(r'^$', home),
)
Template tags
建立首页的 Template 并印出 post_list
首先,在 templates 资料夹底下新增 home.html
:
<!-- home.html -->
{{ post_list }}
打开浏览器进入首页 http://127.0.0.1:8000/,可以看到 post_list 已呈现至网页上了。
显示 Post中的资料
仔细观察印出的 post_list,会发现是以 List 的形式显示。但我们希望的则是:存取这个 Post List 中每个元素的资料,并印出来。
为了达成这个功能,我们会用到 for
这个 Template tag。
for loop
在写 Python 时,若想存取 List 裡的每一个元素,我们会使用 for
迴圈。而在 Django Template 中,也提供了类似的 template tags -- {% for %}。
for
在 Template 中使用类似 Python 的 for 迴圈,使用方法如下:
{% for <element> in <list> %}
...
{% endfor %}
瞭解了 for 的用法后,我们试著印出首页所需的资讯。修改home.html
如下:
<!-- home.html -->
{% for post in post_list %}
<div>
{{ post.title }}
{{ post.created_at }}
{{ post.photo }}
{{ post.content }}
</div>
{% endfor %}
- 开始标籤为
{% for %}
开始;结束标籤为{% endfor %}
- post_list 中有 3 个元素,所以 for 区块中的内容会执行 3 次
- 迴圈中,使用标籤
{{ var }}
,反覆印出每个 post 中的标题、建立时间、照片网址和文章内容
重新整理浏览器,网页上会有首页所需的 post 资讯:
显示照片
现在网页已经有照片网址,我们稍微修改 Template ,让照片以图片方式呈现
<div class="thumbnail">
<img src="{{ post.photo }}" alt="">
</div>
处理没有照片的游记
if...else
另一个常用的 template tags 是 if 判断式,用法如下:
{% if post.photo %}
<div class="thumbnail">
<img src="{{ post.photo }}" alt="">
</div>
{% else %}
<div class="thumbnail thumbnail-default"></div>
{% endif %}
- 符合条件所想要显示的 HTML 放在
{% if
<condition>
%}
区块裡 - 不符合的则放在
{% else %}
区块裡面 - 最后跟 for 一样,要加上
{% endif %}
作为判断式结尾。
在这裡,我们判断如果 post.photo 有值就显示照片,没有就多加上一个 CSS class photo-default
另外处理。
Template filter
除了 template tags ,Django 也内建也许多好用的 template filter。它能在变数显示之前帮你做计算、设定预设值,置中、或是截断过长的内容......等等。使用方法如下:
{{
<variable_name>
|
<filter_name>
:
<filter_arguments>
}}
- < variable_name > -- 变数名称
- < filter_name > -- filter 名称,例如
add
,cut
等等 - < filter_arguments > -- 要传入 filter 的参数
变更时间的显示格式
在这裡,我们只练习一种很常用的 filter - date。它可以将datetime
型别的物件,以指定的时间格式 Date Format ( 例如:Y / m / d
)输出。
我们试著将 created_at
时间,以 年 / 月 / 日
的形式显示:
{{ post.created_at|date:"Y / m / d" }}
完整的 HTML 与 CSS
接著,补上完整的 HTML 标籤,并加上 CSS 样式后,旅游日记首页就完成了。
最终版 home.html 程式码如下:
<!-- home.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>A Django Girl's Adventure</title>
<link href="//fonts.googleapis.com/css?family=Lemon" rel="external nofollow" target="_blank" rel="stylesheet" type="text/css">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="external nofollow" target="_blank" rel="stylesheet" type="text/css">
<link href="//djangogirlstaipei.github.io/assets/css/style.css" rel="external nofollow" target="_blank" rel="stylesheet" type="text/css">
</head>
<body>
<div class="header">
<h1 class="site-title text-center">
<a href="/">A Django Girl's Adventure</a>
</h1>
</div>
<div class="container">
{% for post in post_list %}
<div class="post-wrapper">
<div class="post">
<div class="post-heading">
<h2 class="title">
<a href="#">{{ post.title }}</a>
</h2>
<div class="date">{{ post.created_at|date:"Y / m / d" }}</div>
</div>
{% if post.photo %}
<div class="thumbnail">
<img src="{{ post.photo }}" alt="">
</div>
{% else %}
<div class="thumbnail thumbnail-default"></div>
{% endif %}
<div class="post-content read-more-block">
{{ post.content }}
</div>
<div class="post-footer">
<a class="read-more" href="#">
Read More <i class="fa fa-arrow-right"></i>
</a>
</div>
</div>
</div>
{% endfor %}
</div>
</body>
</html>
打开 http://127.0.0.1:8000/ 看一下你的成果吧!
小结
最后,我们複习一下本章学到的 Template Tag 与 Template Filter:
Template Tag
语法 | 说明 |
---|---|
{% for ... in ... %}...{% endfor %} | 类似 Python 的 for 迴圈,反覆执行 for 区块中的内容 |
{% if %} ... {% else %} ... {% endif %}` | 在 Template Tags 中进行 if/else 的逻辑判断 |
Template Filter
语法 | 说明 | |
---|---|---|
{{ value ** | date:**<date_format> }} |
可以将datetime 型别的物件,以指定的时间格式 Date Format 输出 |
更多建议: