zoukankan      html  css  js  c++  java
  • Django模板语言

    Django模板系统

    官方文档


    常用语法


    {{ 变量名 }} 和 {% 变量名 %}
    
    变量相关的用{{ 变量名 }},逻辑相关的用{% 变量名 %}
    

    变量


    在Django的模板语言中按此语法使用:{{ 变量名 }}。

    当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。 变量的命名包括任何字母数字以及下划线 ("_")的组合。 变量名称中不能有空格或标点符号。
    点(.)在模板语言中有特殊的含义。当模版系统遇到点("."),它将以这样的顺序查询:

    字典查询(Dictionary lookup)
    属性或方法查询(Attribute or method lookup)
    数字索引查询(Numeric index lookup)


    注意事项:
    1. 如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。 2. 如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为'' (空字符串) 。

    案例

    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^template_test/', views.template_test),
    ]
    

    views.py

    from django.shortcuts import render
    
    # Create your views here.
    
    
    def template_test(request):
        ls = [11, 21, 22]
        dic = {'name': '魏新雨咋软'}
    
        class Person(object):
            def __init__(self, name, age, dream):
                self.name = name
                self.age = age
                self.dream = dream
    
            def dream(self):
                return '{}的梦想是成为一个摄影师'.format(self.name)
    
    
        weixinyu = Person('魏新雨', 33, '魏新雨咋软')
        chenjun = Person('陈骏', 33, '陈骏啊, 萨宁啊')
    
        return render(request, 'template_test.html', locals())
    

    /templates/template_test.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="content-Type" charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
    <h1>列表</h1>
    {{ ls }}
    <br>
    <h2>取列表的索引</h2>
    {{ ls.0 }}
    {{ ls.1 }}
    {{ ls.2 }}
    <br>
    <h1>字典</h1>
    {{ dic }}
    <br>
    <h2>取字典的value</h2>
    {{ dic.name }}
    <br>
    <h1>对象</h1>
    <p>{{ weixinyu.name }}: 字 {{ weixinyu.dream }}</p>
    <p>{{ chenjun.name }}: 字 {{ chenjun.dream }}</p>
    
    </body>
    </html>
    


    Filters(过滤器)


    在Django的模板语言中,通过使用 过滤器 来改变变量的显示。

    过滤器的语法:

    {{ value|filter_name:参数 }}
    

    使用管道符|来应用过滤器。

    例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。

    注意事项:

    1. 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
    2. 过滤器可以接受参数,例如:`{{ sss|truncatewords:30 }}`,这将显示sss的前30个单词。
    3. 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:`{{ list|join:', ' }}`
    4. "|" 左右没有空格没有空格没有空格
    

    ### lower

    将字符串转换成小写

    {{ name2|lower }}
    


    join

    使用字符串连接列表,例如Python的str.join(list)

    {{ ls|join:'-' }}
    


    ### default

    设置默认值

    {{ s14|default:'s14这个变量是个空值' }}
    


    lenth

    计算数据的长度

    {{ ls|length }}
    


    filesizeformat

    将数值换成人类易读的文件的单位

    {{ file_size|filesizeformat }}
    


    ### slice

    切片

    {{ name2|slice:'1:-1' }}
    {{ name2|slice:'1:-1:2' }}
    


    data

    指定时间格式

    {{ now|date:'Y-m-d H:i:s' }}
    


    timesince

    变量的时间距离现在的时间多久了, 变量的时间必须是过去的时间

    {{ comment_date|timesince }}
    


    timeuntil

    现在距离变量的时间距离还有多久, 变量的时间必须是未来的时间

    {{ from_date|timeuntil }}
    


    ### safe

    将html字符串在浏览器渲染成html格式的数据(取消对html标签的转义)

    {{ html|safe }}
    


    truncatechars

    如果截取的数量小于文本数量, 则最后三个字符会用...表示

    {{ s1|truncatechars:5 }}
    


    truncatewords

    截取单词, 通过空格来区分单词, 如果截取的字符数小于数据的总长度, 则剩下的字符数用...来代替

    {{ s1|truncatewords:7}}
    


    cut

    移除value中所有的与给出的变量相同的字符串

    {{ s2|cut:' ' }}
    


    divisibleby

    如果value可以被给出的参数整除,则返回 True

    {{ value|divisibleby:“2” }}
    
    <p>{{ 4|divisibleby:'2' }}</p>
    <p>{{ 3|divisibleby:'2' }} </p>
    


    ### **自定义filter**

    定义

    1. 在app目录下创建一个名为 templatetags 的python包
    2. 在上面创建的包内部创建一个python文件: filter.py
    3. 在filter.py文件中按照固定的格式注册的一个自定义的filter
    
    from django import template
    
    # 固定写法, 生成一个注册实例对象
    register = template.Library()
    
    @register.filter(name='generator_sb')  # 告诉django的模板语言, 现在注册一个自定义的filter, name属性则是指定模板语言调用它时候用的名字, 默认不指定是用函数名
    def add_sb(value):
        '''
        给任意指定的变量添加sb
        :param value: | 左边被修饰的那个变量
        :return: 修饰后的内容
        '''
        return value + 'sb'
    
    @register.filter()
    def add_str(value, arg):
        return value + arg
    

    使用

    1. 重启Django项目
    2. 在HTML页面中:{% load python文件名 %}
    3. {{ name2|add_str:'大好人' }}
    


    设置默认时间的显示格式

    settings.py

    USE_L10N = False
    
    DATETIME_FORMAT = 'Y-m-d H:i:s'
    

    {{ now }}
    


    Tags(标签)


    views.py

    def template_test(request):
        ls = [11, 21, 22]
        dic = {'name': '魏新雨咋软'}
        name2 = 'WEI XINYU ZARUAN'
        file_size = 84987394875739397459
        now = datetime.datetime.now()
        html = '<a href="https://www.baidu.com">百度一下</a>'
        s1 = '世情薄人情恶雨送黄昏花易落'
        s2 = "Hello, man, how are you? thank you. And you"
        comment_date = now - datetime.timedelta(days=7)
        from_date = now + datetime.timedelta(days=7)
    
        lis = [
            ['魏新雨咋软', '陈骏啊, 萨宁啊', '傻人', '魏新雨咋软不累赛了'],
            ['魏新雨咋软2', '陈骏啊2, 萨宁啊2', '傻人2', '魏新雨咋软不累赛了2'],
            ['魏新雨咋软3', '陈骏啊3, 萨宁啊2', '傻人3', '魏新雨咋软不累赛了3'],
            ['魏新雨咋软4', '陈骏啊4, 萨宁啊2', '傻人4', '魏新雨咋软不累赛了4'],
        ]
    
        class Person(object):
            def __init__(self, name, age, dream):
                self.name = name
                self.age = age
                self.dream = dream
    
            def dream(self):
                return '{}的梦想是成为一个摄影师'.format(self.name)
    
    
        weixinyu = Person('魏新雨', 33, '魏新雨咋软')
        chenjun = Person('陈骏', 33, '陈骏啊, 萨宁啊')
    
        # return render(request, 'template_test.html', locals())
        return render(request, 'index.html', locals())
    

    需求1 偶数列变色

    index.html

    <table border="1px">
        <thead></thead>
        <tbody>
        {% for row in lis %}
           <tr>
          {% for name in row %}
              {% if forloop.counter|divisibleby:'2' %}
              <td style="color: green">{{ name }}</td>
                  {% else %}
                  <td>{{ name }}</td>
              {% endif %}
          {% endfor %}
    
           </tr>
        {% endfor %}
    
        </tbody>
    </table>
    

    需求2 偶数行变色

    <table border="1px">
        <thead></thead>
        <tbody>
        {% for row in lis %}
           <tr>
          {% for name in row %}
              {% if forloop.parentloop.counter|divisibleby:'2' %}
              <td style="color: green">{{ name }}</td>
                  {% else %}
                  <td>{{ name }}</td>
              {% endif %}
          {% endfor %}
    
           </tr>
        {% endfor %}
    
        </tbody>
    </table>
    

    偶数行偶数列变色

    <table border="1px">
        <thead></thead>
        <tbody>
        {% for row in lis %}
           <tr>
          {% for name in row %}
              {% if forloop.parentloop.counter|divisibleby:'2' and forloop.counter|divisibleby:'2' %}
              <td style="color: green">{{ name }}</td>
                  {% else %}
                  <td>{{ name }}</td>
              {% endif %}
          {% endfor %}
    
           </tr>
        {% endfor %}
    
        </tbody>
    </table>
    


    注意

    模板语言不支持链式比较, 出现链式比较的时候, 比如说 a>b>c, 则会先计算a>b是True还是False, 然后在用0或者1与c再进行比较


    {% if 2 > 1 == 1 %}
    这是真的
        {% else %}
        这是假的
    {% endif %}
    

    输出结果

    这是真的
    

    {% if 2 > 1 > 1 %}
    这是真的
        {% else %}
        这是假的
    {% endif %}
    

    输出结果

    这是假的
    

    if

    {%  if  条件%}
        操作
    {% endif %}
    
    {%  if  条件%}
        操作
    
    {% elif 条件 %}
    
    {% else %}
    
    {% endif %}
    
    注意:
    1. 不支持连续判断  a>b>c  a>b and b>c  
    2. 不支持算数运算  + - * /    add 
    

    for

    <ul>
    {% for user in user_list %}
        <li>{{ user.name }}</li>
    {% endfor %}
    </ul>
    

    for循环可用的一些参数:

    Variable Description
    forloop.counter 当前循环的索引值(从1开始)
    forloop.counter0 当前循环的索引值(从0开始)
    forloop.revcounter 当前循环的倒序索引值(到1结束)
    forloop.revcounter0 当前循环的倒序索引值(到0结束)
    forloop.first 当前循环是不是第一次循环(布尔值)
    forloop.last 当前循环是不是最后一次循环(布尔值)
    forloop.parentloop 本层循环的外层循环

    with

    {% with 变量 as 别名%}
          
      {{ 别名 }}
    {% endwith %}
    

    Csrf token

    1. 放在form表单中
    2. 在表单中添加了一个隐藏的input标签
        name csrfmiddlewaretoken 
        valve  askjdaskdhashdkasd  64 
    
    <input type="hidden" name="csrfmiddlewaretoken" value="2V2pQjIqT0ZDkSImSguofhdLRKAUPyIvZk7zLjzgtNgyna7gdGmoWjF1Rv7UuOBI">
    


    自定义simpletag

    /templatetags/simlpletag.py

    from django import template
    
    register = template.Library()
    
    
    @register.simple_tag
    def join_str(*args, **kwargs):
        print(args)
        print(kwargs)
        if args and not kwargs:
            return "_".join(args)
        if kwargs and not args:
            return "_".join((kwargs['k1'], kwargs['k2']))
        if kwargs and args:
            args_list = list(args)
            args_list.extend([kwargs.get('k1'), kwargs.get('k2')])
    
            return "_".join(args_list)
    

    views.py

    def template_test(request):
        ls = [11, 21, 22]
        dic = {'name': '魏新雨咋软'}
        name2 = 'WEI XINYU ZARUAN'
        file_size = 84987394875739397459
        now = datetime.datetime.now()
        html = '<a href="https://www.baidu.com">百度一下</a>'
        s1 = '世情薄人情恶雨送黄昏花易落'
        s2 = "Hello, man, how are you? thank you. And you"
        comment_date = now - datetime.timedelta(days=7)
        from_date = now + datetime.timedelta(days=7)
    
        lis = [
            ['魏新雨咋软', '陈骏啊, 萨宁啊', '傻人', '魏新雨咋软不累赛了'],
            ['魏新雨咋软2', '陈骏啊2, 萨宁啊2', '傻人2', '魏新雨咋软不累赛了2'],
            ['魏新雨咋软3', '陈骏啊3, 萨宁啊2', '傻人3', '魏新雨咋软不累赛了3'],
            ['魏新雨咋软4', '陈骏啊4, 萨宁啊2', '傻人4', '魏新雨咋软不累赛了4'],
        ]
    
        class Person(object):
            def __init__(self, name, age, dream):
                self.name = name
                self.age = age
                self.dream = dream
    
            def dream(self):
                return '{}的梦想是成为一个摄影师'.format(self.name)
    
    
        weixinyu = Person('魏新雨', 33, '魏新雨咋软')
        chenjun = Person('陈骏', 33, '陈骏啊, 萨宁啊')
    
        # return render(request, 'template_test.html', locals())
        return render(request, 'index.html', locals())
    

    index.html

    <h2>自定义simple_tag</h2>
    {% load simlpletag %}
    {% join_str '魏新雨' '咋软' '是' '个' '大好人' k1='魏新雨' k2='咋软'%}
    

    ### 自定义inclusion_tag

    多用于返回html代码片段

    1. 在app下创建一个templatetags的python包   templatetags名字不能错
    
    2. 在包下写py文件 mypaginator
    
    3. 编辑文件
    
    4. 定义函数
    可以接受参数
    返回一个字典 
    
    5. 函数上加装饰器  ---> @register.inclusion_tag('mypaginator.html')
    
    from django import template
    
    register = template.Library()
    
    @register.inclusion_tag('mypaginator.html')
    def mypaginator(total, current_num):
        total = range(1, total+1)
        current_num = current_num
        return locals()
    
    
    6. 函数返回的字典 交给 pagination.html 渲染
          <!--分页开始-->
    <div>
        <nav aria-label="Page navigation" class="pull-right">
            <ul class="pagination">
                <li>
                    <a href="#" aria-label="Previous">
                        <span aria-hidden="true">&laquo;</span>
                    </a>
                </li>
    
                {% for num in total %}
                    {% if num == current_num %}
                        <li class="active"><a href="#">{{ num }}</a></li>
                    {% else %}
                        <li><a href="#">{{ num }}</a></li>
                    {% endif %}
    
                {% endfor %}
    
                <li>
                    <a href="#" aria-label="Next">
                        <span aria-hidden="true">&raquo;</span>
                    </a>
                </li>
            </ul>
        </nav>
    </div>
    <!--分页结束-->
    


    母版

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="x-ua-compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Title</title>
      {% block page-css %}
      
      {% endblock %}
    </head>
    <body>
    
    <h1>这是母板的标题</h1>
    
    {% block page-main %}
    
    {% endblock %}
    <h1>母板底部内容</h1>
    {% block page-js %}
    
    {% endblock %}
    </body>
    </html>
    

    注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换


    继承母板

    {% extends 'layouts.html' %}
    

    块(block)

    通过在母板中使用{% block  xxx %}来定义"块"
    在子页面中通过定义母板中的block名来对应替换母板中相应的内容
    
    {% block page-main %}
      <p>世情薄</p>
      <p>人情恶</p>
      <p>雨送黄昏花易落</p>
    {% endblock %}
    

    组件

    1. 写一段的代码  nav.html
    2. {% include 'nav.html' %}
    

    静态文件相关

    1. {% load static %}
    static 是个变量, 会获取settings中获取STATIC_URL的值
    
    2. {% static  '相对路径' %}   ——》 去settings中获取STATIC_URL  '/alias/' 和相对路径进行拼接
    <link href="{% static "bootstrap-3.3.7/css/bootstrap.css" %}" rel="stylesheet">
    
    3. {% get_static_prefix %}    ——》 去settings中获取STATIC_URL  '/alias/'
    "{% get_static_prefix %}相对路径"
    <link href="{% get_static_prefix %}dashboard.css" rel="stylesheet">
    


    案例

    图书管理系统源码

  • 相关阅读:
    模块的搜索路径
    循环导入问题
    模块的四种形式
    匿名函数
    面向过程编程
    内置函数
    名称空间和作用域
    函数嵌套
    函数对象
    可变长参数
  • 原文地址:https://www.cnblogs.com/cjwnb/p/11738201.html
Copyright © 2011-2022 走看看