随笔 - 191, 文章 - 1, 评论 - 0, 阅读 - 33496
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Django基础 - 07Template之语法

Posted on   Kingdomer  阅读(61)  评论(0编辑  收藏  举报

 

一、 Template概述

1.1 模板作用

  • 呈现给用户界面; 实现MTV中TV的解耦;
  • VT 有着N:M的关系; 一个View可以调用任意Template, 一个Template可以被任意View使用

1.2 模板内容

  • HTML静态代码
  • 动态插入的代码段(变量、运算、转换和逻辑)

 

二、 模板加载处理流程

  • 加载: 读取指定的html文件
    •  from django.template import loader
    •  template = loader.get_template('index.html')
  • 渲染: 以context设置的数据,处理html文件中模板的语句和变量,生成html网页内容
    •  html = template.render(context)    # context是一个dict类型对象
  • 加载+渲染:
    •  html = loader.render_to_string("index.html", context)
1
2
3
4
5
6
7
8
9
def user_list3(request: HttpRequest):
    users = UserEntity.objects.all()
    msg = '最佳创业团队'
 
    # 加载模板
    template = loader.get_template('user/list2.html')
    # 渲染模板
    html = template.render(context={'msg': msg, 'users': users})
    return HttpResponse(html, status=200)

 

1
2
3
4
5
6
def user_list3(request: HttpRequest):
    users = UserEntity.objects.all()
    msg = '最佳创业团队'
 
    html = loader.render_to_string('user/list2.html', locals(), request)
    return HttpResponse(html, status=200)

  

三、 模板语法

3.1 变量 {{ var }}

变量: 遵循命名规范
点语法(.): 获取属性 car.name ; 调用方法: 不能传递参数 / 索引 cars.0.name / 字典 cars.key

3.1.1 读取列表中的变量  users.2; 读取变量的属性  user.name

1
2
3
4
5
6
7
8
9
10
<body>
    <h3>{{ msg }}</h3>
    <p style="color: green;">
        第三个用户名: {{ users.2.name }}
    </p>
    <ul>
        {% for user in users %}
            <li>{{ user.id }} | {{ user.name }} | {{ user.age }} | {{ user.phone }}</li>
        {% endfor %}
    </ul>

 

 

3.1.2 字典获取key和value

1
2
3
4
5
6
7
8
9
10
11
12
<p style="color: red;">
    今天请客人ID: {{ error_index }}
</p>
<p style="color: white; ">
    <span>VIP:</span>
    <span>{{ vip.name.upper }} - {{ vip.money }}</span>
</p>
<ul>
    {% for key, value in vip.items %}
        <li>{{ key }} = {{ value }}</li>
    {% endfor %}
</ul>

  

3.1.3 变量的索引

1
2
3
def user_list3(request: HttpRequest):
    users = UserEntity.objects.all()
    error_index = random.randint(0, users.count()-1)

 

1
2
3
<p style="color: red;">
    今天谁请客: {{ users.error_index.name }}    # 这样不起作用
</p>

 

3.2 表达式标签 {% %}

for...in 循环

  • 遍历集合(数组,列表):  {% for 变量 in 列表 %}  语句1  {% empty %}  语句2 {% endfor %}
  • forloop: counter 第几次循环,从1开始 / counter0 / revcounter / revcounter0 / first / last
  • empty:   集合为空时的处理;  {% empty %} 集合对象不能为None, 但是没有元素
  • {% cycle "even" "" %}: 轮询的方式选择后面的字符串

if判断

  • if表达式:      {% if expression %} 语句 {% endif%};   表达式必须要关闭
  • if-else:      {% if 表达式 %} 语句 {% else %}       语句 {% endif %}
  • if-elif-else: {% if 表达式 %} 语句 {% elif 表达式 %} 语句 {% endif %}

注释

  • 单行注释: {# 被注释的内容 #}
  • 多行注释: {% comment %} 内容 {% endcomment %}
  • 注释的内容在渲染模板之后,不会保留在HTML页面中

ifequal      如果相等   {% ifequal value1 value2%} 语句 {% endifequal %} 

ifnotequal   如果不相等

 

3.2.1 forloop.counter 是从 1 开始, error_index 是从0开始

1
2
3
4
5
6
7
8
9
10
<ul>
      {% for user in users %}
          <li>{{ forloop.counter }} - {{ user.id }} | {{ user.name }} | {{ user.age }} | {{ user.phone }}</li>
          {% if forloop.counter == error_index %}  
              <p style="color: red;">
                  今天谁请客呢: {{ user.name }}
              </p>
          {% endif %}
      {% endfor %}
  </ul>

 

1
{% if forloop.counter0 == error_index %}

 

 

3.2.2 if 判断 、 for循环、 cycle

1
2
3
4
5
6
7
8
9
10
11
<head>
    <meta charset="UTF-8">
    <title>Django Index主页</title>
    {% include 'base_css.html' %}
    <style>
        .even { background-color: lightgoldenrodyellow; }
        .red { background-color: red; }
        .blue { background-color: blue; }
        .green { background-color: green; }
    </style>
</head>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<table class="table table-bordered table-responsive table-hover">
    <thead>
        <th>ID</th>
        <th>账号</th>
        <th>真实姓名</th>
        <th>手机号</th>
    </thead>
    <tbody>
    {% if users %}
        {% for user in users %}
            <tr class="{% cycle "even" "" %}">
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
            <td>{{ user.realprofile.real_name }}</td>
            <td>{{ user.phone }}</td>
            </tr>
        {% endfor %}
    {% else %}
        <tr>
            <td colspan="4">无数据</td>
        </tr>
    {% endif %}
    </tbody>

 

 

3.2.3 cycle 遍历

1
<tr class="{% cycle "red" "blue" "green" %}

 

3.2.4 empty

1
2
3
4
5
6
7
<ul>
    {% for name in names %}
        <li>{{ name }}</li>
        {% empty %}
        <option>空</option>
    {% endfor %}
</ul>

 

3.2.5  ifequal 

1
<tr {% ifequal forloop.counter 3 %} class="even" {% else %} class="red" {% endifequal %}>

 

3.3 过滤器/逻辑计算

数值运算

  • 加减: 通过加上负数的形式实现减法; {{ store.years|add:5 }} {{ store.years|add:-2 }}
  • 乘除: {% widthratio 变量 分母 分子 %}  例:{% widthratio price 10 1 %} price 的 10分之1
  • 整除: {% if num|divisibleby:2 %}

字符串操作

  • lower:   {{ p.pname|lower }}
  • upper:   {{ p.pname|upper }}
  • capfirst:{{ value|capfirst }} value的第一个字符转换成大写
  • cut:     {{ value|cut:arg }}  从给定value中删除所有arg的值
  • join:    {{ value|join:'-'}} {{ value|join:'-'|escape}}  对iterable进行连接
1
<tr {% ifequal forloop.counter|divisibleby:2 0 %} class="even" {% endifequal %}>  # counter/2余数等于0

 

3.4 default 默认值

格式:  {{ value|default:val }}    {{ store.address|default:'无'}}

 

3.5 日期时间

根据指定格式转换日期为字符串,  {{ dateVal | date:'Y-m-d H:i:s a'}}

格式: F:月份 / g:Hour(1-12)不带前缀0 / G:Hour(0-23)不带前缀0 / l:星期几  / j: 1-31 不带前缀0

1
2
{{ now|date: "Y-m-d" }} # 冒号(:) 后面有空格,报错
django.template.exceptions.TemplateSyntaxError: Could not parse the remainder: ': "Y-m-d"' from 'now|date: "Y-m-d"'

 

3.6 HTML转义

  • escape: 保留原始字符串, "<"之类的符号转换成 &lt; [<  &lt;] [> &gt;] ['] ["] [& &amp;]
  • 在区域开启escape:   {% autoescape on/off %} {% endautoescape %}
  • 将接收到的数据当前普通字符串处理还是当成HTML代码来渲染
  • 渲染成HTML: 不转义  {{ code|safe }}     {% autoescape off %} code {% endautoescape %}
  • 不渲染成HTML: 转义  {{ code|escape }}   {% autoescape on %} code {% endautoescape %}
  • 注意: 开发中尽量保持纯文本; 如果进行html渲染,存在被恶意注入风险
1
2
3
4
5
6
7
8
9
10
11
{{ info | escape }}
 
{% autoescape off %}
    {{ info }}
{% endautoescape %}
 
{% autoescape on %}
    <pre>
        {{ info }}
    </pre>
{% endautoescape %}

 

3.7 其他

  • length:   {{ value|length }}   返回value的长度
  • floatformat
    • {{ value|floatformat }}     34.23444 -> 34.2   34.00000 -> 34     34.26000 -> 34.3
    • {{ value|floatformat:arg }} 34.23444 -> 34.234 34.00000 -> 34.000 34.26000 -> 34.260

3.7.1 显示文件属性 、数值格式化、 转义

1
2
3
4
5
6
7
8
9
>>> import os
>>> from helloDjango.settings import BASE_DIR
>>> file_path = os.path.join(BASE_DIR, 'mainapp/models.py')
>>> os.stat(file_path)
os.stat_result(st_mode=33206, st_ino=562949954054592, st_dev=1828079847, st_nlink=1,
               st_uid=0, st_gid=0, st_size=6674, st_atime=1680343296, st_mtime=1680878778, st_ctime=1680343296)
>>> file_stat = os.stat(file_path)
>>> file_stat.st_size
6674

 

1
2
3
4
5
6
now = datetime.now()
file_dir = os.path.join(settings.BASE_DIR, 'mainapp/')<br>    # files是一个字典, key是 file_name  value是 os.stat(file_dir + file_name)
files = {file_name: os.stat(file_dir + file_name) for file_name in os.listdir(file_dir)
         if os.path.isfile(file_dir+file_name)}
price = 19.1356
img_html = "<img width=200 height=200 src='/media/Fruit.jpeg'>"

  

1
2
3
4
5
6
7
8
9
10
11
{% for path, f_stat in files.items %}
    <p>
        {{ path }} 的文件大小为 {{ f_stat.st_size | filesizeformat }}
    </p>
{% endfor %}
<p>
    价格:  {{ price|floatformat:1 }}
</p>
<p>
    {{ img_html|safe }}
</p>

 

 

 

点击右上角即可分享
微信分享提示