Loading

模板语法之过滤器、标签、自定义过滤器、标签、inclusion_tag、模板的导入、继承、模型层-查询方法all()与filter()、orm常见关键字操作

模板语法之过滤器(类似于内置函数)

语法结构

'{{ 数据对象|过滤器名称:参数 }}  过滤器最多只能额外传输一个参数'

常见过滤器

(django模板语法提供了60+过滤器 我们了解几个即可)
<p>统计数据的长度:{{ s1|length }}</p>
<p>算数加法或者字符串加法(拼接):{{ n1|add:100 }}、{{ s1|add:'hello baby' }}</p>
<p>将数字转成合适的文件计量单位:{{ file_size|filesizeformat }}、{{ file_size1|filesizeformat}}</p>
<p>判断当前数据对象对应的布尔值是否是False>>>:{{ s1|default:'前面的值对应的布尔值是False'  }}、{{ f|default:'前面的值对应的布尔值是False'  }}</p>
{#这个方法如果是true则直接返回对应的字符串,是false则返回default后面的值#}
<p>时间格式化:{{ c_time|date:'Y-m-d' }}</p>
<p>索引切片:{{ s1|slice:'0:3' }}</p>
<p>按照空格截取指定个数的文本{{ s2|truncatewords:4 }}</p>
<p>按照字符截取指定个数的文本(包含三个点):{{ s2|truncatechars:4 }}、{{ s1|truncatechars:6 }}</p>
<p>移除指定的字符:{{ s3|cut:'|' }}</p>
<p>是否取消转换:{{ tag1 }} {{ tag1|safe }}</p>
{#需要把后端的标签语法进行渲染需要加上safe告诉程序这个代码是安全的不必转义,也可以通过后端来实现#}
<p>通过后端实现转换:{{ res }}</p>
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因
显而易见,这样是为了安全。但是有的时候我们可能不希望这些
HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章
中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加
注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标
签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如
果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django
这段代码是安全的不必转义。
ps:最后一个|safe启发了我们以后用django开发全栈项目前端页面代码(主要指HTML代码)也可以在后端编写
# views代码
def index(request):
    s1 = '这是一串字符串'
    n1 = 666
    file_size = 10240
    file_size1 = 10240000
    t = True
    f = False
    c_time = datetime.today()
    s2 = '1 2 3 4 5 7 8 9 0'
    s3 = '1|2|3|4|5'
    tag1 = '<h1>我是一级标签</h1>'
    # 后端来实现safe转换
    from django.utils.safestring import mark_safe
    ttt = '<a href="https://www.baidu.com">百度啊</a>'
    l1 = [11, 22, 33, 44, 55]
    res = mark_safe(ttt)
    user = {'name': 'tuzi', 'pwd': 123, 'hobby': 'ctrl'}
    return render(request, 'index.html', locals())

结果:

image-20220516232704717

模板语法之标签

"""
在django模板语法中写标签的时候 只需要写关键字然后tab键就会自动补全
"""

注释语法

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

语法结构

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

if判断

{% if 条件1 %}
    条件成立后执行的代码
{% elif 条件2 %}
    条件成立后执行的代码
{% else %}
    条件成立后执行的代码
{% endif %}

for循环

提供了forloop关键字
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}
{#first与last用来表示是否是第一次或者最后一次循环#}
{% 代码段 %}
#for循环:
#遍历列表:
{% for i in 列表 %}
#列表不为空时执行
{% empty %}
#列表为空时执行
{% endfor %}
#若加上关键字reversed则倒序遍历:
{% for x in 列表 reversed %}
{% endfor %}
#在for循环中可以通过{{ forloop.counter }}得到for循环遍历到几次


{#
  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 %}
#}

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

{% for foo in user %}
    {{ foo }}
{% endfor %}

{% for foo in user.keys %}
	{{ foo }}
{% endfor %}

{% for foo in user.values %}
	{{ foo }}
{% endfor %}

{% for foo in user.items %}
	{{ foo }}
{% endfor %}

image-20220516163911042

吃啥呢给我掰点

自定义过滤器、标签、inclusion_tag

"""
1.在应用下需要创建一个名为templatetags的文件夹
2.在该文件夹内创建一个任意名称的py文件
3.在该py文件内需要先提前编写两行固定的代码
	from django import template
	register = template.Library()
"""
上述操作完毕之后应该重启一下项目,否则Django无法读取到新建的 templatetags项目包

自定义过滤器:只能接收两个参数

'templatetags文件夹下的mytag文件'
from django import template  # 导入模块
register = template.Library()  # 标准语句都不能改,一字不差
@register.filter(is_safe=True)  # 写函数装饰器
def index(a, b):  # 最多有两个
    return a + b  # 返回两个值之和
'HTML文件'
{% load mytag %}  # 引用模块
{{ n1|index:666 }}  # 通过函数名使用

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

'templatetags文件夹下的mytag文件'
@register.simple_tag(name='my_tag')
def func1(a, b, c, d):
    return a + b + c + d
'HTML文件'
{% my_tag 1 2 3 4 %}  # 参数之间空格隔开即可

自定义inclusion_tag

'templatetags文件夹下的mytag文件'
@register.inclusion_tag('left.html')
def func2(n):
    l1 = []
    for i in range(1, n + 1):
        l1.append(f'第{i}页')
    return locals()
{% func2 10 %}

'left.html'
<ul>
    {% for foo in l1 %}
        <li>{{ foo }}</li>
    {% endfor %}
</ul>
'''该方法需要先作用于一个局部html页面 之后将渲染的结果放到调用的位置'''

我的好朋友啊你在吃什么

模板的导入(了解)

类似于将html页面上的局部页面做成模块的形式 哪个地方想要直接导入即可展示
eg:有一个非常好看的获取用户数据的页面 需要在网站的多个页面上使用
  	策略1:拷贝多份即可
    策略2:模板的导入
   
使用方式
	{% include 'menu.html' %}

模板的继承

{#1.先在模板中通过block划定将来可以被修改的区域#}
{% block content %}
  	<h1>主页内容</h1>
{% endblock %}
{# 2.子板继承模板 #}
{% extends 'home.html'%}
{# 3.对引入的模板块进行从写 #}
{% block demo %}
{# 4.子页面也支持使用父页面的功能 #}
{{ block.super }}
"""
模板上最少应该有三个区域
	css区域、内容区域、js区域
子页面就可以有自己独立的css、js、内容
"""
eg:
    在引入css的地方开设一个可以被修改的区域
    {% block css %}
    {% endblock %}
    在引入js的地方开设一个可以被修改的区域
    {% block js %}
    {% endblock %}

模型层

前期数据准备

"""
django 自带的sqlite3数据库功能很少,并且针对日期类型不准确
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", "Pythonexerciseday54_lianxi.settings")
    import django
    django.setup()
2.pycharm提供
	python console
    

数据准备

import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Pythonexerciseday54_lianxi.settings")
    import django

    django.setup()

    from app01 import models

    models.User.objects.create(name='jason', age=18)
    models.User.objects.create(name='tuzi', age=28)
    models.User.objects.create(name='tony', age=38)
    models.User.objects.create(name='kevin', age=48)
    models.User.objects.create(name='oscar', age=58)
    models.User.objects.create(name='stt', age=68)
    models.User.objects.create(name='tian', age=78)
    models.User.objects.create(name='tian2', age=78)

查询方法all()与filter()

all() 返回表里面所有的数据

# res = models.User.objects.all()# 返回user表里面所有的数据,会封装成一个个对象  QuerySet可以看成是列表套对象

filter() 筛选数据

filter()# 括号内填写筛选条件,不写相当于all()  QuerySet可以看成是列表套对象
filter(pk=1)  # 想通过主键筛选数据 可以直接写pk 会自动定位到当前表的主键字段 无需自己查看具体字段名称
filter(pk=1)[0]  # 直接获取数据对象  QuerySet支持索引取值,但是django不支持使用,因为索引不存在会直接报错
filter(pk=1).first()  # 获取结果集中第一个对象 使用自带的方法  推荐使用封装的方法,不会出现索引超出范围报错的情况
filter(pk=1,name='kevin').first()  # filter 括号内支持传多个参数,逗号隔开,多个参数之间默认是and关系
filter().filter().filter().filter()  # 只要是QuerySet对象就可以继续点对象方法(类似与jq的链式操作)
filter().last()  # 获取结果集中最后一个对象

filter() 用法详细

# res = models.User.objects.filter()# 括号内填写筛选条件,不写相当于all()  QuerySet可以看成是列表套对象
# res = models.User.objects.filter(pk=1)  # 想通过逐渐筛选数据 可以直接写pk 会自动定位到当前表的主键字段 无需自己查看具体字段名称
# res = models.User.objects.filter(pk=1)[0]  # 直接获取数据对象  QuerySet支持索引取值,但是django不支持使用,因为索引不存在会直接报错
# res = models.User.objects.filter(pk=1).first()  # 获取结果集中第一个对象 使用自带的方法  推荐使用封装的方法,不会出现索引超出范围报错的情况
# res = models.User.objects.filter(pk=1,name='kevin').first()  # filter 括号内支持传多个参数,逗号隔开,多个参数之间默认是and关系
# res = models.User.objects.filter().filter().filter().filter()  # 只要是QuerySet对象就可以继续点对象方法(类似与jq的链式操作)
res = models.User.objects.filter().last()  # 获取结果集中最后一个对象

yeah 比耶表情包

orm常见关键字操作

values()	        返回包含对象具体值的字典的QuerySet
values_list()	    与values()类似,只是返回的是元组而不是字典。
distinct()	        对查询集去重
order_by()	        对查询集进行排序	
exclude()	        排除满足条件的对象
reverse()	        反向排序
count()	            统计结果集的个数
exists()            校验结果集中有没有数据
get()               直接获取数据对象

用法详细

'''values()'''
res = models.User.objects.all().values('name','pk')  # QuerySet可以看成列表套字典<QuerySet [{'name': 'jason', 'pk': 1}]>
res = models.User.objects.values('name','pk')  # QuerySet可以看成列表套字典 指定字段,all不写也表示从所有数据中操作
res = models.User.objects.filter(pk=2).values('name')  # 可以看成是对结果集进行字段的截取

'''values_list()'''
res = models.User.objects.all().values_list('name', 'age')  # QuerySet可以看成列表套元组<QuerySet [('jason', 18)]>

'''distinct()'''	
res = models.User.objects.all().distinct()  # 数据对象中如果包含主键,不可能去重
res = models.User.objects.values('name').distinct()  # 这样可以进行去重操作,结果还是一个QuerySet

'''order_by()'''
res = models.User.objects.order_by('age')  # 默认是升序
res = models.User.objects.order_by('-age')  # 改为降序
res = models.User.objects.order_by('age','pk')  # 也支持多个字段依次排序

'''exclude()'''
res = models.User.objects.exclude(name='jason')  # 取反操作

'''reverse()'''
res = models.User.objects.reverse()  # 不起作用
res = models.User.objects.order_by('age').reverse()  # 只有在order_by排序之后才可以

'''count()'''
res = models.User.objects.count()  # 统计结果集的个数

'''exists()'''
res = models.User.objects.exists()  # 有数据就返回True
res = models.User.objects.filter(name='jason666').exists()  # 校验结果集中有没有数据  有True  没有False

'''get()'''
res = models.User.objects.get(pk=1)  # 直接获取数据对象,但是不推荐使用,因为条件不存在会立即报错

疯狂打call疯狂打call疯狂打call疯狂打cal疯狂打call

posted @ 2022-05-16 22:44  香菜根  阅读(83)  评论(0编辑  收藏  举报