叶觉的Django之旅【03-模板配置、变量、标签、继承】

前言:前一章说到,路由与分路由app的大致构造,在这基础上将加入模板对各个app进行进一步加工。考虑到废话太多,本章起将偏重于实例使用。

模板配置

  • 创建模板文件 templates,包含所有的app模板
  • 创建一个测试用模板 book_index.html
├── book
├── db.sqlite3
├── manage.py
├── mydjango
└── templates
    └── book
        └── book_index.html

  • 模板路径拼接 settings.py -> TEMPLATES
'DIRS': [os.path.join(BASE_DIR, 'templates')],

三种渲染方法

  • 渲染的方式有以下三种,其中第一、二种在实例中并不常用。
  • 硬编码,一般情况下硬编码的形式并不使用,在之前的章节中,用到了硬编码的形式去测试。
def index_mode1(request):
    return HttpResponse('硬编码页面')
  • 获取模板再加载
from django.template.loader import get_template

def index_mode2(request):
    temp = get_template('book/book_index.html')
    html = temp.render()
    return HttpResponse(html)
  • 使用 render 进行渲染()
from django.shortcuts import render

def index_mode(request):
    return render(request, 'book/book_index.html')

模板变量

  • 语法使用 {{ 变量名 }}
  • 支持传递的类型 (字典、模型、方法、函数、列表、元组)
  • 在 render 中使用 context 参数进行传递
class ClassTest(object):
    def __init__(self, name):
        self.name = name

    def run(self):
        return '我是类的run'


def test():
    return "我是一个测试的函数"


list1 = ['a', 'b', 'c', 'd']
tu1 = ('a', 'b', 'c', 'd')
string1 = '我是一个测试的字符串'
dict1 = {
    'key1': '我是测试用的字典value'
}


# 使用render 渲染]
def index_mode(request):
    return render(request, 'book/book_index.html', context={
        'classTest': ClassTest('一个名字'),
        'test': test,
        'list1': list1,
        'tuple1': tu1,
        'string1': string1,
        'dict1': dict1
    })
  • 传递后出现的效果
    在这里插入图片描述

过滤器

  • 作用:对变量进行过滤。在真正渲染出来之前,过滤器会根据功能处理好变量,然后得出结果后再替换掉原来的变量展示出来
  • 语法{{ 变量名|对应方法 }}
{{name|first}} # 取得字符串第一个字符
{{name|join:'*' # 拼接
{{name|slice:"1:3"}} # 切割
  • 常用过滤器表
过滤器 用途
add 字符串、数字、列表相加。失败则返回空字符串
default 提供一个默认值,原值被django认定为False时使用默认值
first 返回可迭代对象第一个值
last 返回可迭代对象最后一个值
date 格式化日期和时间
time 格式化时间
join 拼接,同python的join用法
length 返回字符串或是列表的长度
length_is 字符串或者列表长度是否为指定的值
lower 所有字符串变成小写
truncatechars 根据给定的参数进行字符截断。超过则用…表示
truncatewords 同上一个,此过滤器以单词为单位进行截断
capfirst 首字母大写
slice 切割可迭代对象,与python切片用法一致,区间为前闭合后开放
striptags 去掉所有html标签
safe 关闭变量的自动转义
floatformat 浮点数格式化
  • date 与 time 的过滤器格式
    用例说明
# 传入一个时间对象 datetime.datetime.now
# 如不使用格式化参数,则使用默认格式
{{now|date:'Y/m/d H:i:s'}}
{{now|time:'h:i:s'}}
  • date 和 time 格式化参数表
参数 说明
Y 四位数的年。如:1999
y 两位数的年。如:99
m 两位数的月。如:01,09,12
n 一位数的月。如:1,9,12
d 两位数的日。如:01,09,12
j 一位数的日。如:1,9,12
g 12小时制的一位数的小时。如:1,9,12
G 24小时制的一位数的小时。如:0,8,23
h 12小时制的两位数的小时。如:01,09,12
H 24小时制的两位数的小时。如:01,13,24
i 分钟。从00~59
s 秒。从00~59

静态文件

  • 主项目目录下创建 static 文件,根据需求分类创建子文件夹
├── static
    ├── css
    │   └── test.css
    ├── img
    │   └── panda.jpg
    └── js
        └── test.js
  • 设置静态文件目录路径,同 templates 设置方法,settings.py -> STATICFILES_DIRS
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]
  • 静态文件的导入以及三种常见的文件导入示例
{% load static %}    # 加载静态文件

# 常见的三种文件导入示例
<link rel="stylesheet" href="{% static 'css/test.css' %}"> 
<script src="{% static 'js/test.js' %}"></script>
<img src="{% static 'img/panda.jpg' %}" alt="加载失败">

模板标签

  • 语法,由符号组合 {% %} 来定义单个的的成对出现的符号组{% tag %}{% endtag %}
  • 常用标签的使用示例
# 传入一个list1 [i for i in range(1, 10)]

{# for 循环 #}
{% for i in list1 %}
    {{ i }}
{% endfor %}

{# 条件循环 #}
{% for i in list1 %}
    {% if i == 3 %}
        现在是 i=3 的那次循环
    {% endif %}
{% endfor %}

{# 外层循环计数 #}
{% for i in list1 %}
    {% if forloop.counter == 3 %}
        现在是第三次循环 {{ i }}
    {% endif %}
{% endfor %}

{# 反向的外层循环计数,下表从大到小 #}
{% for i in list1 %}
    {% if forloop.revcounter == 3 %}
        {{ i }}
    {% endif %}
{% endfor %}

{# 父级循环计数 #}
{% for i in list1 %}
    {% for j in list1 %}
        {% if forloop.parentloop.counter == 3 %}
            {{ i }}, {{ j }} <br>
        {% endif %}
    {% endfor %}
{% endfor %}

{# 跳转使用 #}
# {% url "url_name" arg1 arg2 %} 其中需要在urls.py中定义页面的name属性
<a href="{% url 'ceshi2' %}">跳转</a>

{# 批量取消自动转义 #}
{% autoescape off %}
    html
{% endautoescape %}
  • 更多常用标签可以查看 defaulttags.py 源码

模板继承

  • 模板的作用:当站点出现重复代码时候,使用模板对网站进行模块化操作,会使得网站的构造清晰明了,且省去了大量的不必要代码,为网站的搭建省却时间。
  • base、block 和 extends
    在模板的继承过程中,首要创建一个基类模板 “base.html”,使用block标签在需要被子模块覆盖的地方设置 block。在子模板中,使用 extends 标签进行模板继承,继承后使用 block 对基类中已设置的block进行页面填充。

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}
        未命名的测试页面  {# 若该block没有填充则使用默认值 #}
    {% endblock %}</title>
</head>
<body>
{#文章标题#}
{% block headline %}

{% endblock %}

{#文章内容#}
{% block content %}

{% endblock %}

{% block tail %}

{% endblock %}
</body>
</html>

需要进行继承的子页面

{% extends 'test/base.html' %}

{% block title %}
    首页
{% endblock %}

{% block headline %}
    <h3>无题</h3>
{% endblock %}


{% block content %}
    <p>这是一篇文章,此文章有很多东西,但是不知道内容是什么</p>
    <p>这是一篇文章,此文章有很多东西,但是不知道内容是什么</p>
{% endblock %}

{% block tail %}
    <br>
    结束了,不用看了
{% endblock %}
  • block.super
    对于继承的block内容,如需引用父类原本的内容,使用{{ block.super }}进行引用。
{% block title %}
    {{ block.super }}首页
{% endblock %}
  • include 标签
    在 block 中引用外部页面的代码块
{% include 'test/test_templates.html' %}
  • 总结:
    • 模板的继承使用extends标签实现,通过使用block来子模板开放接口。
    • extends 必须是模板中的第一个出现的标签
    • 子模板中的所有内容,必须出现在父模板定义好的block中,否则django将不进行渲染
    • 如果在某个block中要使用父模板的内容,用block.super获取
    • 如果在某个block中需要引入外部页面的代码块,用include标签进行加载。

参考文献

https://www.jianshu.com/p/a5c5e9c51242 作者:木叶望将

发布了24 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_39177678/article/details/103270892