• Django-模板层


    模板语法之变量

    Django 模板中遍历复杂数据结构的关键是句点字符

    句点符

    views.py

    def index(request):
        '''
        模板语法:
        {{ }} 渲染变量用的
            1深度查询  句点符
            2过滤器 {{val | filter_name:参数}}
        {% %} 渲染标签用的
        :param request:
        :return:
        '''
        name="yuan"
        i=10
        l=[111,222,333]
        info={"name":"yuan","age":22}
        b=True
    
        class Person(object):
    
            def __init__(self,name,age):
                self.name=name
                self.age=age
    
        alex=Person("alex",35)
        egon=Person("egon",33)
    
        person_list = [alex,egon]
        return render(request,"index.html",locals())  #locals():获取当前页面中所有变量

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
    
    
    <h1>index</h1>
    
    <p>{{ name }}</p>
    
    <p>{{ i }}</p>
    
    <p>{{ b }}</p>
    
    <p>{{ info }}</p>
    
    <p>{{ alex }}</p>
    
    <p>{{ person_list }}</p>
    
    <hr>
    
    <strong>深度查询</strong>
    <p>{{ l.1 }}</p>
    <p>{{ info.name }}</p>
    <p>{{ edward.age }}</p>
    <p>{{ person_list.0.name }}</p>
    
    </body>
    </html>

    过滤器

    语法:

    {{obj|filter__name:param}}

    default

    如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:

    {{ value|default:"nothing"}}

    length

    返回值的长度。它对字符串和列表都起作用。例如:

    {{ value|length }}

    如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。

    filesizeformat

    将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB''4.1 MB''102 bytes', 等等)。例如:

    {{ value|filesizeformat }}

    如果 value 是 123456789,输出将会是 117.7 MB

    date

    如果 value=datetime.datetime.now()

    {{ value|date:``"Y-m-d"}}

    slice

    {{ value|slice:"2:-1"}}

    truncatechars

    如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。

    {{ value|truncatechars:9}}  #按字符数截取

    {{ text|truncatewords:3 }} #按单词截取

    upper、lower

    转大写和转小写

    safe
    为了网页数据安全,Django的模板中会对HTML标签和JS等语法标签进行自动转义。有的时候我们可能不希望这些HTML元素被转义,使用safe

    {{ link|safe }}

    标签

    标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。

    一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %}}

    for标签

    遍历每一个元素:

    {% for i in list %}
            <p>{{ i }}</p>
        {% endfor %}

    可以利用{% for obj in list reversed %}反向完成循环。

    遍历一个字典:

    {% for key,val in dic.items %}
        <p>{{ key }}:{{ val }}</p>
    {% endfor %}

    for empty 标签

    for标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。

    循环序号可以通过{{forloop}}显示

    {% for person in person_list %}
            <p>{{ forloop.counter0 }} {{ person.name }} {{ person.age }}</p>
        {% empty %}
            <p>列表为空</p>
        {% endfor %}

    if 标签

    {% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

    登录注册页面应用

     <hr>
        {% if user %}
            <p>
                <a href="">hi {{ user }}</a>
                <a href="">注销</a>
            </p>
        {% else %}
            <p>
                <a href="">登录</a>
                <a href="">注册</a>
            </p>
        {% endif %}
        <hr>

    with 标签

    使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的

    {% with business.employees.count as total %}
        {{ total }} employee{{ total|pluralize }}
    {% endwith %}

    csrf_token

    这个标签用于跨站请求伪造保护

    <form action="" method="post">
        {% csrf_token %}
        name <input type="text" name="user">
        pwd <input type="text" name="pwd">
        <input type="submit">
    </form>

    3. 自定义标签与过滤器

    1、在settings中的INSTALLED_APPS注册当前app,不然django无法找到自定义的simple_tag.

    2、在app中创建templatetags模块(模块名只能是templatetags)

    3、创建任意 .py 文件,如:my_tags.py

    from django import template
    
    register = template.Library()  # 固定名称register
    
    
    # 最多传两个参数,应用在if语句
    
    @register.filter  # multi_filer = register.filter(multi_filer)
    def multi_filter(x, y):
        return x * y
    
    
    # 可以传任意多的参数,不可用if语句
    @register.simple_tag()
    def multi_tag(x, y,z,v):
        return x * y * z * v

    4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py

    {% load my_tags %}

    5、使用simple_tag和filter(如何调用)

    -------------------------------.html
      {% load xxx %}        
      # num=12
      {{ num|filter_multi:2 }} #24
      {{ num|filter_multi:"[22,333,4444]" }}
      {% simple_tag_multi 2 5 %}  参数不限,但不能放在if for语句中
      {% simple_tag_multi num 5 %}

    注意:filter可以用在if等语句后,simple_tag不可以

    {% if num|filter_multi:30 > 100 %}
        {{ num|filter_multi:30 }}
    {% endif %}

    模板继承 (extend)

    模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。

    base.html,定义了一个可以用于两列排版页面的简单HTML骨架

    “子模版”的工作是用它们的内容填充空的blocks。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        {% block title %}
            <title>base</title>  <!-- 如果扩写了就是扩写的,不扩写就还是用base -->
        {% endblock %}
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
            .header {
                width: 100%;
                height: 50px;
                background-color: #369;
            }
        </style>
    </head>
    <body>
    
    <div class="header"></div>
    
    <div class="container">
        <div class="row">
            <div class="col-md-3">
                {% include 'advertise.html' %}
            </div>
            <div class="col-md-9">
                {% block con %}
                    <h4>content</h4>
                {% endblock %}
            </div>
        </div>
    </div>
    
    
    </body>
    </html>

    block 标签定义了三个可以被子模版内容填充的block。 block 告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。

    advertise.html

    <div class="advert">
        <div class="panel panel-danger">
            <div class="panel-heading">Panel heading without title</div>
            <div class="panel-body">
                Panel content
            </div>
        </div>
    
        <div class="panel panel-warning">
            <div class="panel-heading">
                <h3 class="panel-title">Panel title</h3>
            </div>
            <div class="panel-body">
                Panel content
            </div>
        </div>
    
        <div class="panel panel-primary">
            <div class="panel-heading">Panel heading without title</div>
            <div class="panel-body">
                Panel content
            </div>
        </div>
    </div>

    index.html

    {% extends 'base.html' %}
    
    {% block title %}
        <title>index</title>
    {% endblock %}
    
    
    {% block con %}
        <div class="col-md-9">
            <h3>index</h3>
    
            <p>{{ name }}</p>
    
            <p>{{ i }}</p>
    
            <p>{{ b }}</p>
    
            <p>{{ info }}</p>
    
            <p>{{ alex }}</p>
    
            <p>{{ person_list }}</p>
    
            <hr>
    
            <strong>深度查询</strong>
            <p>{{ l.1 }}</p>
            <p>{{ info.name }}</p>
            <p>{{ edward.age }}</p>
            <p>{{ person_list.0.name }}</p>
    
    
            <h3>过滤器</h3>
    
            <p>{{ now | date:"Y-m-d" }}</p>
    
            <p>{{ empty_list | default:"数据为空" }}</p>
    
            <p>{{ file_size | filesizeformat }}</p>
    
            <p>{{ text | truncatechars:9 }}</p>  <!-- 按字符截 -->
    
            <p>{{ text | truncatewords:10 }}</p>  <!-- 按单词截 -->
    
            <p>{{ link | safe }}</p>  <!-- 告诉django正常渲染就行,不用防止xss攻击 -->
    
            <hr>
    
    
            <h3>for 标签</h3>
    
            {% for i in l %}
                <p>{{ i }}</p>
            {% endfor %}
    
    
            {% for i in info %}
                <p>{{ i }}</p>
            {% endfor %}
    
            {% for person in person_list %}
                <p>{{ person.name }},{{ person.age }}</p>
            {% endfor %}
    
    
            {% for person in person_list %}
                <p>{{ forloop.counter }} {{ person.name }},{{ person.age }}</p>
            {% endfor %}
    
    
            {% load my_tags %}
            <h3>自定义过滤器</h3>
    
            <!-- 自定义过滤器 -->
            <p>{{ num_ten | multi_filter:20 }}</p>  <!-- 200 -->
    
            <!-- 自定义标签 -->
    
            <p>{% multi_tag 10 10 10 10 %}</p>  <!-- 10000 -->
    
    
            <!-- 自定义过滤器可以用于if判断,自定义标签不能 -->
    
            {% if num_ten|multi_filter:15 > 100 %}
                <p>100</p>
            {% else %}
                <p>{{ num_ten }}</p>
            {% endif %}
        </div>
    
    {% endblock %}

    orders.html

    {% extends 'base.html' %}]
    
    
    {% block title %}
        <title>orders</title>
    {% endblock %}
    
    
    {% block con %}
        {{ block.super }}  <!-- 既保留base的,又保留扩写的 -->
        <h4>订单</h4>
    {% endblock con %}  <!-- 可以加名字,增加可读性 -->

    需要注意的是:

    • 如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。

    • 在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。

    • 如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %} 中。

    • {{ block.super }} 子模板会继承父类中已经有的block,而不是会覆盖
    • 为了更好的可读性,你也可以给你的 {% endblock %} 标签一个 名字,这个方法帮你清楚的看到哪一个  {% block %} 标签被关闭了。
    • 不能在一个模版中定义多个相同名字的 block 标签。  
  • 相关阅读:
    1、编写一个简单的C++程序
    96. Unique Binary Search Trees
    python 操作redis
    json.loads的一个很有意思的现象
    No changes detected
    leetcode 127 wordladder
    django uwsgi websocket踩坑
    you need to build uWSGI with SSL support to use the websocket handshake api function !!!
    pyinstaller 出现str error
    数据库的读现象
  • 原文地址:https://www.cnblogs.com/hexiaorui123/p/10503767.html
Copyright © 2020-2023  润新知