模板语法与模型层部分知识
- 模板语法之过滤器
- 模板语法之标签
- 自定义过滤器、标签、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
自定义过滤器、标签需知:
- 自定义过滤器、标签是在py文件中自定义的。
- 在应用下需要创建一个名为templatetags的文件夹,并在这个文件夹中创建py文件。
- py文件名称任意。
- 该py文件内需要先提前编写两行固定的代码
from django import template
register = template.Library()
- 使用时需要先使用模板语法导入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() | 直接获取数据对象,但是数据不存在会报错 |