2018-12-20

template基本使用

Python 代码编写和 HTML 设计是两项不同的工作,将页面的设计和Python的代码分离开会更干净简洁更容易维护。我们通过 Django的 模板系统 (Template System)来实现这种模式

1. 使用 {{双大括号}} 来引用变量

(venv) E:\Django-1.11.17\testkarl>python3 manage.py shell
>>> from django.template import Template, Context
>>> t = Template('show item 2: {{ items.2 }}')
>>> c = Context({'items': ['apple', 'banana', 'pear', 'orange']})
>>> t.render(c)
'show item 2: pear'

# 同一模板,多个上下文,一旦有了模板对象,你就可以通过它渲染多个context,无论何时我们都可以
# 像这样使用同一模板源渲染多个context,只进行 一次模板创建然后多次调用render()方法渲染会
# 更为高效:
# Low
for name in ('John', 'Julie', 'Pat'):
    t = Template('Hello, {{ name }}')
    print t.render(Context({'name': name}))

# Good
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'):
    print t.render(Context({'name': name}))

Django 模板解析非常快捷。 大部分的解析工作都是在后台通过对简短正则表达式一次性调用来完成。 这和基于 XML 的模板引擎形成鲜明对比,那些引擎承担了 XML 解析器的开销,且往往比 Django 模板渲染引擎要慢上几个数量级。

2. 深度变量的查找(万能的句点号)

在到目前为止的例子中,我们通过 context 传递的简单参数值主要是字符串,然而,模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。在 Django 模板中遍历复杂数据结构的关键是句点字符 (.)。

# 1.使用句点访问列表索引
>>> from django.template import Template, Context
>>> t = Template('show item 2: {{ items.2 }}')
>>> c = Context({'items': ['apple', 'banana', 'pear', 'orange']})
>>> t.render(c)
'show item 2: pear'

# 2.使用句点访问字典的值
>>> from django.template import Template, Context
>>> persion = {'name':'Karl', 'age':'30'}
>>> t = Template('{{persion.name}} is {{persion.age}} years old.')
>>> c = Context({'persion':persion})
>>> t.render(c)
'Karl is 30 years old.'

# 3.使用句点访问对象的属性
>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1997, 7, 20)
>>> d.year
1997
>>> d.month
7
>>> d.day
20

# 4.使用句点访问对象的方法
>>> from django.template import Template, Context
>>> t = Template('{{var}} -- {{var.upper}} -- {{var.lower}} -- {{var.isdigit}}')
>>> t.render(Context({'var':'KarlPython123'}))
'KarlPython123 -- KARLPYTHON123 -- karlpython123 -- False'
## 注意:这里调用方法时没有使用小括号(),而且无法给该方法传参,因此只能调用无参的方法

3. django 过滤器

过滤器 描述 示例
upper 以大写方式输出 {{ user.name | upper }}
add 给value加上一个数值 {{ user.age | add:”5” }}
addslashes 单引号加上转义号
capfirst 第一个字母大写 {{ ‘good’ | capfirst }} 返回”Good”
center 输出指定长度的字符串,把变量居中 {{ “abcd” | center:”50” }}
cut 删除指定字符串 {{ “You are not a Englishman” | cut:”not” }}
date 格式化日期
default 如果值不存在,则使用默认值代替 {{ value | default:”(N/A)” }}
default_if_none 如果值为None, 则使用默认值代替
dictsort 按某字段排序,变量必须是一个dictionary {% for moment in moments | dictsort:”id” %}
dictsortreversed 按某字段倒序排序,变量必须是dictionary
divisibleby 判断是否可以被数字整除 {{ 224 | divisibleby:2 }} 返回 True
escape 按HTML转义,比如将”<”转换为”&lt”
filesizeformat 增加数字的可读性,转换结果为13KB,89MB,3Bytes等 {{ 1024 | filesizeformat }} 返回 1.0KB
first 返回列表的第1个元素,变量必须是一个列表
floatformat 转换为指定精度的小数,默认保留1位小数 {{ 3.1415926 | floatformat:3 }} 返回 3.142 四舍五入
get_digit 从个位数开始截取指定位置的数字 {{ 123456 | get_digit:’1’}}
join 用指定分隔符连接列表 {{ [‘abc’,’45’] | join:’*’ }} 返回 abc*45
length 返回列表中元素的个数或字符串长度
length_is 检查列表,字符串长度是否符合指定的值 {{ ‘hello’ | length_is:’3’ }}
linebreaks 用<p>或
标签包裹变量
{{ “Hi\n\nDavid” | linebreaks }} 返回<p>Hi</p><p>David</p>
linebreaksbr
标签代替换行符
linenumbers 为变量中的每一行加上行号
ljust 输出指定长度的字符串,变量左对齐 {{‘ab’ | ljust:5}} 返回 'ab'
lower 字符串变小写
make_list 将字符串转换为列表
pluralize 根据数字确定是否输出英文复数符号
random 返回列表的随机一项
removetags 删除字符串中指定的HTML标记 {{value | removetags: “h1 h2”}}
rjust 输出指定长度的字符串,变量右对齐
slice 切片操作, 返回列表 {{[3,9,1] | slice:’:2’}} 返回 [3,9]
slugify 在字符串中留下减号和下划线,其它符号删除,空格用减号替换 {{ '5-2=3and5 2=3' | slugify }} 返回 5-23and5-23
stringformat 字符串格式化,语法同python
time 返回日期的时间部分
timesince 以“到现在为止过了多长时间”显示时间变量 结果可能为 45days, 3 hours
timeuntil 以“从现在开始到时间变量”还有多长时间显示时间变量
title 每个单词首字母大写
truncatewords 将字符串转换为省略表达方式 {{ 'This is a pen' | truncatewords:2 }} 返回This is ...
truncatewords_html 同上,但保留其中的HTML标签 {{ '<p>This is a pen</p>' | truncatewords:2 }} 返回<p>This is ...</p>
urlencode 将字符串中的特殊字符转换为url兼容表达方式 {{ ‘http://www.aaa.com/foo?a=b&b=c’ | urlencode}}
urlize 将变量字符串中的url由纯文本变为链接
wordcount 返回变量字符串中的单词数
yesno 将布尔变量转换为字符串yes, no 或maybe {{ True | yesno }},{{ False | yesno }},{{ None | yesno }} 分别返回yes, no, maybe

4. 自定义过滤器

4.1 第一步: 在app目录下创建包 templatetags (包名不能改)

  • 在templatetags下创建py文件,文件名随意,比如

4.1.1 自定义simple_tag, 不能在模板中使用if判断

from django import template
from django.utils.html import format_html
import datetime

register = template.Library()

@register.simple_tag
def page_cut(current_page, loop_page):
    #分页: 固定显示前后5页
    differ = abs(current_page - loop_page)
    if differ < 5:
        li = '''<li class=""><a href="?page=%s">%s<span class="sr-only">(current)</span></a></li>''' % (loop_page, loop_page)
        return format_html(li)
    else:
        #这里一定要返回一个空字符串,否则在前端会显示一系列的None
        return ''

4.1.2 自定义过滤器函数filter

  • 因为sample_tag不能使用if判断,所以才有了它
  • 最多只能有两个参数,一个是变量值,一个是选项值
from django import template
from django.utils.html import format_html
import datetime

register = template.Library()

@register.filter
def time_color(exp_date):
    #给一个月内到期的html标签加上class属性
    startdate = datetime.datetime.now().date()
    enddate = startdate + datetime.timedelta(30)
    if (enddate - exp_date).days > 0 and (enddate - exp_date).days <= 30:
        td = '''<td class="%s">%s</td>''' % ('exp_date', exp_date)
        return format_html(td)
    elif (enddate - exp_date).days > 30:
        td = '''<td class="outof">%s</td>''' % (exp_date)
        return format_html(td)
    else:
        td = '''<td>%s</td>''' % (exp_date)
        return format_html(td)

4.2 第二步: html引用

  • *在文件开头导入 {% load my_page %} *
<tbody>
        {% for project in projects_list %}
        <tr>
            <td><a href="{% url 'projects_detail' project.id %}">{{ project.com_name }}</a></td>
            <td>{{ project.name}}</td>
            <td>{{ project.domain }}</td>
            <td>{{ project.get_status_display }}</td>
            {{ project.exp_date|time_color }}
            <td>{{ project.ftp }}</td>
        </tr>
        {% endfor %}
    </tbody>
<!-- 页码导航 -->
<nav>
  <ul class="pagination">
    {% if projects_list.has_previous %}
        <li class=""><a href="?page={{ projects_list.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>
    {% endif %}

    {% for page_num in projects_list.paginator.page_range %}
     {% if page_num == projects_list.number %}
        <li class="active"><a href="?page={{ page_num }}">{{ page_num }}<span class="sr-only">(current)</span></a></li>
     {% else %}
         #分页标签
        {% page_cut projects_list.number page_num %}
     {% endif %}
    {% endfor %}

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

推荐阅读更多精彩内容