zoukankan      html  css  js  c++  java
  • Django之模板层

    一、模板语法

    1、后端向前端传输数据的方式

    # 第一种
     return render(request,'index.html',{'n':n})
    
     # 第二种
     # locals()会将当前所在的名称空间中的变量名字全部传递给前端页面
     return render(request,'index.html',locals())  
    
    
    模板常用法语:
    {{     }}    变量相关
    {% %}    逻辑相关
    
    在Django中的模板语言用{{ 变量名 }}来使用变量,而这个变量的来源通常是在视图函数里面产生的,通过render方法返回到前端,前端通过此语法来使用该变量。

    2、后端的传递的数据类型

    #后端的传递的数据类型可以是:int、str、list、dict、tuple、set、function....
    
    #传递的变量命名规则:包括任何字母数字以及下划线 ("_")的组合, 变量名称中不能有空格或标点符号。
    
    #模板语法规定:使用句点符(就是点号:.)来取出变量中的相关数据,比如字典、列表、元祖、属性方法(对象)
    
    #这里还需要强调一点:模板语法是不支持传参的。
    
    
    举例:
    ##后端:views.py##
    l = [1,2,3,4,5,user_obj]
    user_obj = models.Book.object.filter(id=1).first()
    d = {'name': 'sgt', 'password': '123'}
    
    
    前端:使用模板语法,来处理后端传递过来的变量
    
    {# 取l中的第一个参数 #}
    {{ l.0 }}
    {# 取字典d中相应的值 #}
    {{ d.name }}
    {{ d.keys }}
    {{ d.values }}
    {{ d.items }}
    
    {# 取对象的name属性 #}
    {{ user_obj.name }}
    
    {# .操作只能调用不带参数的方法 #}
    {{ l.5.name }}
    
    {% with l.5.name  as h %}
    {{ h }}
    {% endwith %}
    {# 将 l.5.name找到的数据起名为h,这样就可以通过h这个名字得到 l.5.name的值 #}

    函数和类:

    ##函数
    后端:
    def func():
            return '你调用了我?'
    
    前端:
    {{ func }}
    
    显示结果:你调用了我?
    
    在前端调用后端的函数名(当然此函数名肯定在locals()里面)时,会调用该函数(函数名加括号),得到函数调用的返回值,如果无返回值则为None;
    #后端传函数名到前端,会自动加括号调用,但是不支持传参;
    
    
    ##类
    后端:
        class Demo(object):
            def __init__(self, name):
                self.name = name
                
            def func(self):
                return self.name
            
            @classmethod
            def test(cls):
                return 'cls'
            
            @staticmethod
            def foo(name,age):
                return 'static_foo'
            
        obj = Demo('sgt')
    
    如果类里面加入:
            def __str__(self):
                return 'Sgt帅得一塌糊涂!'
    
    那么{{ obj }}的结果就会变成:Sgt帅得一塌糊涂!(因为__str__会拦截打印动作,在前端{{ obj }}实际上就是类似于打印obj.

    另外:

    1.前端调用后端数据类型(不需要传参)的内置方法
    
    2.模板语法的注释不会展示到前端页面
    
    3.原生的html注释会展示到前端:<!--我是原生的html注释-->

    二、过滤器

    1、过滤器介绍

    在Django的模板语言中,通过使用 过滤器 来改变变量的显示。
    
    过滤器的语法: {{ value|filter_name:参数 }}
    
    使用管道符"|"来应用过滤器。
    
    例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。
    
    注意事项:
        过滤器支持链式操作,即一个过滤器的输出结果作为另一个过滤器的输入
        过滤器可以接收参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
        过滤器参数包含空格的话,必须用引号包裹起来,比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
        管道符‘|’左右没有空格。一定要注意,没有空格

    2、使用案例

    前端统计字符串的长度:
    <p>{{ s|length }}</p>
    
    前端获取数据如果是空就返回default后面默认的参数值:
    <p>{{ flag|default:'你这个东西是个空'}}</p>
    
    将数字格式化成表示文件大小的单位:
    <p>{{ file_size|filesizeformat }}</p>
    
    
    <p>{{ ctime }}</p>    {#June 11,2019,10:36 a.m.#}
    格式化时间(不要加百分号)
    <p>{{ ctime|date:'Y-m-d' }}</p>     {# 2019-06-11 #}
    
    字符串的切片操作:
    <p>{{ res|slice:'0:8' }}</p>
    <p>{{ res|slice:'0:8:2' }}</p>
    
    截取固定的长度的字符串 三个点也算:
    <p>{{ s|truncatechars:10 }}</p>
    按照空格截取文本内容:
    <p>{{ res|truncatewords:4 }}</p>
    
    字符串和数字不能混用(返回空):
    <p>{{ 'haha'|add:'hehe' }}</p> {# hahahehe #}
    <p>{{ 249|add:1 }}</p>    {# 250 #}
    
    
    ht = <h1>我是h1标签</h1>
    sr = <script>alter(123)</script>
    
    <p>{{ ht }}</p>    {# <h1>我是h1标签</h1> #} 不识别h1标签
    <p>{{ sr }}</p>    {# <script>alter(123)</script> #} 不识别script标签
    
    前端取消转义
    <p>{{ ht|safe }}</p>  加 |safe 后能识别标签
    <p>{{ sr|safe }}</p>
    
    后端取消转义
    from django.utils.safestring import mark_safe
    res = mark_safe('<h1>我是h1标签</h1>')

    三、标签

    1、for循环

    后端
    ll = [1, 2, 3, 4, 5]
    
    前端
    {% for foo in ll %}
         <p>{{ foo }}</p>
    {% endfor %}
    
    结果显示:
    1
    2
    3
    4
    5

    2、forloop

    后端
    ll = [1, 2, 3, 4, 5]
    
    前端
    {% for foo in ll %}
         <p>{{ forloop }}</p>
    {% endfor %}

    image

    forloop值为下方的字典 :

    {'revcounter':反向序号, 'last'(是否是最后一位,True或者False), 'revcounter0':反向索引, 'counter0':(索引), 'parentloop':引用的父级循环对象没有为{}, 
    'first': (是否是最后一位,True或者False), 'counter':(序号,从1开始)}

    3、if判断

    {% for foo in l %}
    if else
        {% if flag %}
            <p>flag不为空</p>
            {% else %}
            <p>flag是空</p>
        {% endif %}
        
    {#(l = ['a', 'b', 'c', 'd', 'e'])#}
    {% for foo in l %}
        {% if forloop.first %}
            <p>这是我的第一次</p>
        {% elif forloop.last %}
            <p>这是最后一次了啊</p>
        {% else %}
            <p>嗨起来!!!</p>
        {% endif %}
        {% empty %}   <!--如果l = [],上面的for循环不会进行,只会走这一步-->
            <p>你给我的容器类型是个空啊,没法for循环</p>
    {% endfor %}
    
    
    结果:
    l = ['a', 'b', 'c', 'd', 'e']
    这是我的第一次
    嗨起来!!!
    嗨起来!!!
    嗨起来!!!
    这是最后一次了啊
    
    l = []
    你给我的容器类型是个空啊,没法for循环

    四、自定义过滤器/标签/inclusion_tag

    1、必须做的三件事

    1.在应用名下新建一个名为templatetags文件夹(必须叫这个名字)
    
    2.在该新建的文件夹内新建一个任意名称的py文件
    
    3.在该py文件中需要固定写下面两句代码

    2、在app01项目程序文件夹新建templatetags文件夹,在此文件夹内新建一个mine.py文件,打开mine.py文件>>输入:

    from django import template
    register = template.Library()
    
    # 自定义过滤器
    @register.filter(name='my_filter')
    def index(a, b):
        return a*b
    
    # 自定义标签:
    @register.simple_tag
    def plus(a, b, c):
        return a+b+c

    前端html文件内使用过滤器或者标签:

    {% load mine %}   <!-- 要使用自定义过滤器和标签,需要先加载自己定义的文件 -->
    {{ 9|my_filter:11 }}  <!-- 使用自定义过滤器,注意这里需要用name的值作为使用方法 -->
    {% my_tag 1 2 3 %}  <!-- 使用自定义标签,注意这里需要用name的值作为使用方法 -->
    
    结果:
    99 
    6

    3、自定义inclusion_tag

    inclusion_tag的作用:创建一个动态的html页面文件a.html,这个页面文件a可以在另外一个页面b中被调用,实现这个页面a应该有的功能。
    主要作用:通过渲染一个模板来显示一些数据。
    
    # mine.py文件  创建inclusion_tag
    from app01 import models 
    from django import template
    register = template.Library()
    
    @register.inclusion_tag('inclusion_t_test.html', name='my_inclusion')
    def func():
        book_list = models.Book.objects.all()
        return {'list': book_list} 
    
    
    #将book_list的QuerySet对象列表传进inclusion_t_test.html文件
    <!-- inclusion_t_test.html文件,被导入的html文件-->
    <table>
        <thead>
            <tr>
                <th>id</th>
                <th>title</th>
                <th>price</th>
            </tr>
        </thead>
        <tbody>
            {% for obj in list %}
                <tr>
                    <td>{{ obj.id }}</td>
                    <td>{{ obj.title }}</td>
                    <td>{{ obj.price }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    
    
    调用的html页面文件:
    {% load mine %}    <!-- 必须要先加载创建标签的文件-->
    {% my_inclusion %}  <!-- 调用inclusion_t_test.html页面文件,这里使用该标签的name来调用-->

    五、模板的继承与模板的导入

    1、模板的继承

    模板的继承:我们需要使用一个网页中一些固定不变的部分,在不用自己写或者复制的前提下,只需要写几段代码就能拿来在一个新的网页使用,就像一个模板,模板
    中变化的地方我们自己指定,其他地方不变,值只变化我们指定的地方。
    
    
    {% block 给区域起的名字 %}
        前端代码
        ...
    {% endblock %}
    
    
    <!--通常情况下一个模板中应该至少有三块-->
    {% block css %}
      页面css代码块
    {% endblock %}
    
    {% block js %}
      页面js代码块
    {% endblock %}
    
    {% block content %}
      页面主体内容
    {% endblock %}

    模板继承:

    {#先继承模板所有的内容#}
            {% extends 'home.html' %}
    
    {#然后根据block块的名字修改指定区域的内容#}
            {% block content %}
                <h1>登录页面</h1>
                    <form action="">
                        <p>username:<input type="text" class="form-control"></p>
                        <p>password:<input type="text" class="form-control"></p>
                        <input type="submit" class="btn btn-success">
                    </form>
            {% endblock %}
    
    
    如果在一个block模板中需要保留原始的内容则可以在这个block中任意你想要的位置添加一个{{ block.super }},就可以保留原内容;

    模板导入:

    将一段html当做模块的方式导入到另一个html展示:
    {% include '想导入的html文件名' %}
    
    模板导入与自定义inclusion_tag的区别:模板导入的页面内容是静态的、不变的,而通过自定义inclusion_tag导入的页面文件可以是动态的,可动性自己掌控。

    六、静态文件配置

    {% load static %}  
        
        <link rel='stylesheet' href="{% static 'css/mycss.css'%}">  # 第一种方式
        <link rel='stylesheet' href="{% get_static_prefix %}css/mycss.css">  # 第二种方式
  • 相关阅读:
    171 01 Android 零基础入门 03 Java常用工具类02 Java包装类 01 包装类简介 01 Java包装类内容简介
    170 01 Android 零基础入门 03 Java常用工具类01 Java异常 08 Java异常总结 01 异常总结
    169 01 Android 零基础入门 03 Java常用工具类01 Java异常 07 异常链 01 异常链简介
    168 01 Android 零基础入门 03 Java常用工具类01 Java异常 06 自定义异常 01 自定义异常类
    167 01 Android 零基础入门 03 Java常用工具类01 Java异常 05 使用throw和throws实现异常处理 02 使用throw抛出异常对象
    166 01 Android 零基础入门 03 Java常用工具类01 Java异常 05 使用throw和throws实现异常处理 01 使用throws声明异常类型
    165 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 05 return关键字在异常处理中的使用
    DevExpress WPF v20.2版本亮点放送:全新升级的PDF Viewer
    界面控件DevExpress使用教程:Dashboard – 自定义导出
    DevExpress WinForms帮助文档:表单控件
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/11812100.html
Copyright © 2011-2022 走看看