模板语法学习

模板语法学习



前言

在项目中,我们所需要使用或展示的数据通常是动态获取的;因此,前端怎么动态的去展示出后端或者数据库的数据,就成了我们的问题,而模板语法就是答案。


前端接收数据与取值


前端想接受到后端数据只能通过{{ }}和{% %}

取值只能通过.进行取值,既可以.索引也可以点.key`

{{}}   # 变量相关,用在接收后端传递过来的数据、过滤器、自定义过滤器
{% %}   # 逻辑相关,用在标签(if判断 for循环)、自定义标签simple_tag、inclusion_tag、模版继承extend和导入include
<p>{{ d.key }}</p>  # 字典使用点key方式
<p>{{ my_str.0 }}</p>  # 字符串使用点索引的方式
<p>{{ l.0 }}</p>            # 列表使用点索引的方式
<p>{{ obj.get_class }}</p>      # 对象点属性或方法的方式

模板语法传值


字典传值

​ 该方法直接将前端需要的数据通过字典传出去,优点在于节约资源,缺点在于麻烦

# views.py
def index(request):
    my_str = 'string'
    my_int = 11
    my_list = [1, 2, 3]
    my_tup = (1, 2, 3)
    my_dic = {'name': 'python', 'age': 18}
    my_set = {1, 3, 4}
    my_bool = True
    my_float = 11.11
    return_dic = {
        'str': my_str,
        'int': my_int,
        'list': my_list,
        'dict': my_dic,
        'tuple': my_tup,
        'set': my_set,
        'bool': my_bool,
        'float': my_float,
    }
    return render(request, 'render_html.html', return_dic)
  
# render_html.html
<body>
    {{ str }}
    {{ int }}
    {{ list }}
    {{ dict }}
    {{ tuple }}
    {{ set }}
    {{ bool }}
    {{ float }}
</body>

locals传值

​ 该方法通过locals直接将当前视图函数中所有的变量传给前端页面,优点在于方便,缺点在于节约资源

# views.py
def index(request):
    my_str = 'string'
    my_int = 11
    my_list = [1, 2, 3]
    my_tup = (1, 2, 3)
    my_dic = {'name': 'python', 'age': 18}
    my_set = {1, 3, 4}
    my_bool = True
    my_float = 11.11
    return render(request, 'render_html.html', locals())

# render_html.html
<body>
    {{ my_str }}
    {{ my_int }}
    {{ my_list }}
    {{ my_tup }}
    {{ my_dic }}
    {{ my_set }}
    {{ my_bool }}
    {{ my_float }}
</body>

模板语法之过滤器


作用

在模板语言中,可以通过过滤改变变量的显示,过滤器就类似于内置函数


数据结构

{{ 数据对象|过滤器名称:参数 }}  # 单个过滤器只能接受一个参数

常见过滤器

<p>{{ 数据对象|length }}</p>  # 统计数据的长度
<p>{{ int数据对象|add:111 }}、{{ str数据对象|add:'big baby' }}</p>  # 对数字类型进行求和,字符串类型进行拼接
<p>{{ 文本数字|filesizeformat }}</p>  # 将数字转成合适的文件计量单位
<p>{{ 数据对象|default:'数据对象为False' }}</p>  # 检测对象是否为True,如果不是则返回后面的值
<p>{{ 时间数据对象|date:'Y-m-d' }}</p>  # 时间格式化
<p>{{ 数据对象|slice:'0:8' }}</p>  # 索引切片
<p>{{ 文本数据对象|truncatewords:2 }}</p>  # 按照空格截取指定个数的文本
<p>{{ 文本数据对象|truncatechars:5 }}</p>  # 按照字符个数截取文本(包含三个点)
<p>{{ info|cut:'|' }}</p>  # 移除指定的字符
<p>{{ 使用了前端语法的数据对象 }}、{{ 使用了前端语法的数据对象|safe }}</p>  # 默认不允许前端语法的数据生效,使用safe后生效

模板语法之标签


此处的标签并不是指代HTML文档中的标签,而是模板语法中的逻辑使用,使用逻辑可对后端传过来的数据进行操作。


语法结构

{% 名字 ...%}
{% end名字 %}


if判断

{% if 条件1 %}
    <p>条件一展示的标签</p>
{% elif 条件2 %}
    <p>条件二展示的标签</p>
{% else %}
    <p>不满足上面条件展示的标签</p>
{% endif %}

for循环

提供了forloop关键字

# views.py
from django.shortcuts import render


# Create your views here.
def index(request):
    my_str = 'string'
    my_dic = {'name': 'python', 'age': 18}
    my_list = []
    return render(request, 'render_html.html', locals())
<!--render_html.html-->
<body>
    <p>i就是每次循环得到的元素值,而每次循环得到的forloop是每个元素的详细信息</p>
    {% for i in my_str %}
        <p>{{ i }}, {{ forloop }}</p>
    {% endfor %}
    {% for i in my_list %}
    	<p>我不会被执行</p>
    	{% empty %}
    		<p>因为my_list是空的,所以我会被执行</p>
    {% endfor %}
    <!--for循环处理字典的方法与python后端非常类似-->
    {% for foo in my_dic.keys %}
        <p>{{ foo }}</p>
    {% endfor %}

    {% for foo in my_dic.values %}
        <p>{{ foo }}</p>
    {% endfor %}

    {% for foo in my_dic.items %}
        <p>{{ foo }}</p>
    {% endfor %}
    
</body>

----------------------------------页面结果如下----------------------------------
s, {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': True, 'last': False}

t, {'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 5, 'revcounter0': 4, 'first': False, 'last': False}

r, {'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 4, 'revcounter0': 3, 'first': False, 'last': False}

i, {'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False}

n, {'parentloop': {}, 'counter0': 4, 'counter': 5, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}

g, {'parentloop': {}, 'counter0': 5, 'counter': 6, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
......

----------------------------------结果分析-------------------------------------------
每行的第一个元素就是for循环后得到的i值;
每行后面的字典就是forloop,每个元素的详细信息,代表意思分别如下:
	counter0:从零开始计算索引,当前元素的索引值
	counter:从1开始计算索引,当前元素的索引值
	revcounter:从1开始计算索引,将索引值反过来后当前元素的索引值
	revcounter0:从0开始计算索引,将索引值反过来后当前元素的索引值
	first:表示当前元素是否是第一个元素
	last:表示当前元素是否是最后一个元素
  
for+if使用

{% for i in l1 %}
    {% if forloop.first %}
        <p>这是第一次循环</p>
    {% elif forloop.last %}
        <p>这是最后一次循环</p>
    {% else %}
        <p>中间循环</p>
    {% endif %}
    {% empty %}
        <p>for循环对象为空 自动执行</p>
  {% endfor %}

自定义过滤器、标签、inclusion_tag


类似于python中的自定义函数,有三个前提条件

  1. 在应用下需要创建一个名为templatetags的文件夹

  2. 在该文件夹内创建一个任意名称的py文件

  3. 在该py文件内需要先提前编写两行固定的代码

    from django import template
    register = template.Library()


自定义过滤器

​ 自定义过滤器需要在templatetags目录下创建的py文件中定义过滤器,功能和内置的过滤器相同,都是接收并处理视图函数传过来的数据,如果内置过滤器不能满足需求即可使用自定义过滤器。需要注意的是自定义过滤器最多也只能接收两个参数,比如定义一个计算两个元素之和的过滤器:

# templatetags/my_filter.py
from django import template

register = template.Library()
@register.filter(name='sum')  # name=自定义过滤器的名字
# 过滤器的功能
def my_sum(v1, v2):  # 过滤器接收两个参数
    return v1 + v2

  # 前端使用 
<body>
{% load sum %}  <!--先加载自定义过滤器-->
{{ my_int }}
{{ my_int|my_sum:666 }}  
</body>

自定义简单标签

​ 同样需要在templatetags目录下创建py文件,可以和自定义过滤器使用同一个py文件,但是建议分开方便管理,前端页面调用自定义标签对数据进行处理,如果模板语法中现有的标签不满足对数据的逻辑处理就可以自定义标签对数据进行处理。可以接受任意的参数,比如下述自定义标签:

# templatetags/my_tag.py
from django import template

register = template.Library()
# 自定义标签,参数可以有多个
@register.simple_tag(name='my_tag')  # name=自定义标签的名字
def index(a,b,c):
    return f'{a}{b}{c}'
  
# 前端使用
<body>
{% load my_tag %}
<!--自定义标签使用语法:{% 标签名 参数1 参数2 参数3....%},标签多个参数彼此之间空格隔开-->
{% my_tag 'a' 'b' 'c' %}
</body>

自定义inclusion_tag

自定义inclusion_tag的调用相比其他的产生了改变,稍微比较绕

首先依旧在templatetags目录下创建py文件,并定义方法,然后定义方法指定该方法的返回数据是a.thml,然后b.html调用了该方法;实际上是b.html将参数传给了a.html页面,再将渲染完的页面和数据返回给b.html

# templatetags/my_inclusion_tag.py
from django import template
register = template.Library()  # 固定的两句

@register.inclusion_tag(filename='a.html', name='my_inclusion')  # 将结果返还到a.html
def test(n):
    data = []
    for i in range(1, n + 1):
        l1.append(f'第{i}页')
    return locals()
{% test 10 %}

a.html使用该方法
<ul>
    {% for foo in l1 %}
        <li>{{ foo }}</li>
    {% endfor %}
</ul>

b.html调用a.html的页面
<body>
{% load my_inclusion_tag %}  <!--首先需要加载inclusion_tag-->
{% my_inclusion 5 %}  <!--调用inclusion_tag,语法为{% 自定义inclusion_tag的函数名 参数%}-->
</body>

模板的导入

​ 当我们觉得html页面上的某一块我们很喜欢,想在别的地方展示;我们就可以将这块做出一个模块,需要的时候直接导入展示即可。

{% include 'menu.html' %}  # 使用方式

注释语法补充

<!---->  是HTML的注释语法
{# #}		 是django模板语法的注释
"""
HTML的注释可以在前端浏览器页面上直接查看到
模板语法的注释只能在后端查看 前端浏览器查看不了
"""

页面模板继承

会想我们所使用过的网页,会发现一种情况;进行页面点击后,不是整个页面发生了变化,只是局部页面发生了改变;为了实现这个效果,我们就要知道什么是页面模板的继承。

第一步,需要选好一个模板页面,作为其他页面继承的页面。

第二步,在继承模板页面的其他页面的HTML文档中清空所欲内容,因为这个页面已经不是整体的页面了,而是局部的一块页面,称为子页面,在子页面上需要书写下述代码;

{% extends '模板页面的文件名' %}
<!--这行代码的意思就是继承了模板页面上的所有的内容-->

第三步,在模板页面上划定可以被修改的区域,划定方式如下述代码:

<!--模板页面-->
{% block content %}  // content是可以被修改部分的名字,可以是任意的
	模板页面上可以被修改的部分
{% endblock%}

第四步,在子页面上声明想要修改模板页面上的内容:

{% block content %}  // content是可以被修改部分的名字,可以是任意的
	子页面独有的内容
{% endblock%}

数据库反向迁移命令

​ 主要用于操作已经存在的表,将映射出来的类写入models.py即可

1.数据库正向迁移命令(将类操作映射到表中)
	python3 manage.py makemigrations
  python3 manage.py migrate
2.数据库反向迁移命令(将表映射成类)
	python3 manage.py inspectdb

测试环境搭建

​ 当我们需要操作orm,单并不想通过网络请求的时候,我们就可以搭建测试环境,为了方便

1.自己搭建
    	import os
			if __name__ == "__main__":
    			os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
    			import django
    			django.setup()
    2.pycharm提供
    	python console

posted @ 2022-05-16 20:46  Eason辰  阅读(54)  评论(0)    收藏  举报