博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Django基础 - 07Template之语法

Posted on 2023-04-09 18:11  Kingdomer  阅读(57)  评论(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)
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)

 

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

<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

    <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 变量的索引

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

 

    <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开始

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

 

{% if forloop.counter0 == error_index %}

 

 

3.2.2 if 判断 、 for循环、 cycle

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

 

    <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 遍历

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

 

3.2.4 empty

    <ul>
        {% for name in names %}
            <li>{{ name }}</li>
            {% empty %}
            <option>空</option>
        {% endfor %}
    </ul>

 

3.2.5  ifequal 

<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进行连接
<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

{{ 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渲染,存在被恶意注入风险
    {{ 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 显示文件属性 、数值格式化、 转义

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

 

    now = datetime.now()
    file_dir = os.path.join(settings.BASE_DIR, 'mainapp/')
# 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'>"

  

    {% 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>