模板语法与模型层部分知识


目录
  • 模板语法之过滤器
  • 模板语法之标签
  • 自定义过滤器、标签、inclusion_tag
    • 自定义过滤器
    • 自定义简单标签
    • 自定义inclusion_tag
  • 模板语法之导入
  • 模板的继承
  • 模板语法之注释
  • 前期数据准备
  • all()与filter()
  • ORM操作常见方法

模板语法之过滤器

过滤器类似于内置函数,但是这种内置函数最多只能额外传输一个参数。

语法结构:

{{ 数据对象|过滤器名称:参数 }}

常见过滤器

过滤器 作用
s|length 计算数据s的长度
s|add:x 将s与x相加
s|filesizeformat 将数字s转成合适的文件计量单位(KB、MB..)
s|deafult:'x' 判断数据s的布尔值是否是False,是则返回x
s|date:'x' 将时间s格式化成x
s|slice:'m:n' 索引切片,相当于s[m,n]
s|truncatewords:x 按照空格截取x个文本,多出来的用省略号显示
s|truncatechars:x 截取x个字符,多出来的用省略号显示
s|cut:'x' 移除指定的字符x
s|safe 将s按照html格式转换

针对safe过滤器,我们也可以在后端实现:使用mark_safe方法后将结果传给页面,页面就能识别标签语法了。

from django.utils.safestring import mark_safe
tag = '内容'
res = mark_safe(ttt)

模板语法之标签

语法结构:

{{ 标签名称... }}
	内容
{{ end标签名称 }}

if判断

{% if 条件1 %}
	内容
{% elif 条件2 %}
	内容
{% else %}
	内容
{% endif %}

for循环

{% for 变量 in 容器类型 %}
	内容
{% empty %}
	for循环对象为空时执行
{% endfor %}

其中{% empty %}可不写。

对于for循环,模板语法还提供了forloop关键字,是一个字典类型数据,里面存储了一些for循环的信息:{{ forloop }}

{
    'parentloop': {},
    'counter0': 0,  # 从0计数,0代表for循环的第一次 
    'counter': 1,  # 从1计数,1代表for循环的第一次 
    'revcounter': 4,  # counter相反的结果
    'revcounter0': 3,  # counter0相反的结果
    'first': True,  # 是否是第一次循环
    'last': False  # 是否是最后一次循环
}

补充:针对字典同样提供了keys、values、items方法

自定义过滤器、标签、inclusion_tag

自定义过滤器、标签需知:

  1. 自定义过滤器、标签是在py文件中自定义的。
  2. 在应用下需要创建一个名为templatetags的文件夹,并在这个文件夹中创建py文件。
  3. py文件名称任意。
  4. 该py文件内需要先提前编写两行固定的代码
from django import template
register = template.Library()
  1. 使用时需要先使用模板语法导入py文件名
{% load py文件名 %}

自定义过滤器

自定义过滤器只能接收两个参数,第一个形参接收调用过滤器的数据,第二个形参接收自己填写的数据,比如自定义一个相减的过滤器

@register.filter
def reduce(a, b):
    return a - b

使用:将s减5

{% load py文件名 %}
{{ s|reduce:5 }}

自定义简单标签

自定义简单标签可以接收任意的参数。

@register.simple_tag(name='func')
def f(a, b, c):
    return a + b + c

使用:

{% load py文件名 %}
{% func 1 2 3 %}

对于自定义标签,需要设置name属性才能使用,并且使用时是用{%%}这个符号的。

自定义inclusion_tag

inclusion_tag可以把写好的一些标签放入到网页中。

该方法需要先作用于一个局部html页面,之后将渲染的结果放到调用的位置。

@register.inclusion_tag('content.html')
def func(n):
    l1 = [i for i in range(n)]
    return l1

content.html

    {% for i in l %}
  • {{ i }}
  • {% endfor %}

页面调用:

{% func 10 %}

模板语法之导入

类似于将html页面上的局部页面做成模块的形式,哪个地方想要直接导入即可展示。

比如我想要让home.html与index.html一样,那么我只需要将index.html导入到home.html中即可。

home.html

{% include 'index.html' %}

模板的继承

类似于面向对象的继承:继承了某个页面就可以使用该页面上所有的资源,继承后我们就可以根据页面进行局部更改。

使用:

首先先在通过block划定将来可以被修改的区域:

{% block 区域名称 %}
	标签内容
{% endblock %}

子页面继承:

{% extends '父页面' %}

子页面修改可以被修改的区域:

{% block 区域名称 %}
	标签内容
{% endblock %}

子页面还可以重复使用父页面的内容:

{% block 区域名称 %}
	{{ block.super }}
	{{ block.super }}
	...
{% endblock %}

补充:

一般来说,一个页面上最少应该有三个区域:css区域、内容区域、js区域,这样子页面就可以有自己独立的css、js、内容。

模板语法之注释

模板语法的注释

{# 注释内容 #}

HTML的注释可以在前端浏览器页面上直接查看到,模板语法的注释只能在后端查看,前端浏览器查看不了。

前期数据准备

数据库正向迁移命令(通过类创建表):

python manage.py makemigrations
python manage.py migrate

数据库反向迁移命令(通过表创建类):

python manage.py inspectdb

补充

如果想要不通过网络请求操作orm,我们可以在测试环境中操作:

1.自己搭建(应用下的test.py)

import os
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "setting.py文件路径")
    import django
    django.setup()

需要写上如上固定代码,填上你自己的setting.py文件路径参数即可,之后的测试代码都写在if判断中进行测试。

2.pycharm提供测试环境

针对日期类型,有如下参数:

op_time = models.DateTimeField(auto_now=True)
"""
auto_now:每次修改数据的时候都会自动更新当前时间
auto_now_add:在数据被创建出来的时候会自动记录当前时间,之后不人为修改的情况下保持不变
"""

all()与filter()

方法 作用
all() 查询所有数据
filter(条件) 筛选数据

在filter()不写参数时,与all()返回的结果是一致的。

这两个方法返回的结果都是QuerySet,可以看成是一个列表里放了多个对象,如果想要取出里面的对象可以用索引的方式:

QuerySet[0]  # 取里面的第一个数据对象

也可以用一些方法取出对象:

QuerySet.first()  # 取里面的第一个数据对象
QuerySet.last()  # 取里面的最后一个数据对象

这两种取对象的方式使用第二种更好一些,因为就算QuerySet里没有对象取出时也不会报错。

对于filter()筛选,有专门针对主键筛选的参数:

filter(pk=)  # 通过主键筛选

ORM操作常见方法

方法 作用
values(字段1,字段2...) 查询指定字段,返回值相当于列表套字典
values_list(字段1,字段2...) 查询指定字段,返回值相当于列表套元组
distinct() 将查询出来的数据去重
order_by(字段) 默认根据指定字段升序排序,字段前加'负号(-)'可以改成降序
order_by(字段1,字段2...) 多字段排序
exclude(条件) 查询不符合条件的数据
reverse() 查询结果倒置,只有在排序后在起作用
count() 返回结果集个数
exists() 判断结果集中是否有数据,有返回True,没有返回False
get() 直接获取数据对象,但是数据不存在会报错