Django5

模板层之标签

标签类似于python的流程控制

1.if判断

<body>
    {% if 条件 %}  条件一般是模板语法传过来的数据  直接写名字使用即可
        条件成立执行的代码
    {% elif 条件1 %}
        条件1成立执行的代码
    {% else %}
        条件都不成立执行的代码
    {% endif %}
</body>

2.for循环

forloop 模板语法自带的变量名

{% for i in s %}
        {% if forloop.first %}
            <p>这是第一次哟~</p>
        {% elif forloop.last %}
            <p>这是最后一次!</p>
        {% else %}
            <p>{{ i }}</p>
        {% endif %}
        {% empty %}
            <p>empty专门用来判断空的时候,当in后面是空的时候执行这个,给予提示</p>
    {% endfor %}

解析:
forloop内置对象:运行结果解析
'counter0': 从0开始计数
'counter' : 从1开始计数
 
'first': True,判断循环的开始
'last' : Tues,判断循环的结束

image

3.with语法起别名

# with起别名
{% with d.hobby.3.info as nb  %}
    <p>{{ nb }}</p>
    在with语法内就可以通过as后面的别名快速的使用到前面非常复杂获取数据的方式
    <p>{{ d.hobby.3.info }}</p>
{% endwith %}


解析:
可以通过as后面的别名快速的使用到前面非常复杂获取数据的方式
取别名后原来的名字也能正常使用
命名规范: 只能在with代码块儿的范围之内才能使用别名

自定义过滤器、标签及inclusion_tag

1.自定义过滤器、标签及inclusion_tag要准备的三步

1.在应用下创建一个名字必须叫templatetags的目录
2.在上述目录下创建任意名称py文件
3.在上述py文件内先编写两行固定的代码
  from django import template
  register = template.Library()

image

2.自定义过滤器最大只能接收两个参数

# mytag.py
from django import template
register = template.Library()


# 参数   过滤器   过滤器名字
@register.simple_tag(name='myadd')
def func1(a,b):
  return a+b 

# 加载自定义文件名
{% load mytags %}
<p> {{ i|myadd:1}}</p>

3.自定义标签 参数没有限制

# 参数    标签      标签名字
@register.simple_tag(name='mytag')
def func2(a,b,c,d,e):
  return f'{a}-{b}-{c}-{d}-{e}'

# 加载自定义文件名
{% load mytags %}
{% mytag 'jason' 'kevin' 'oscar' 'tony' 'lili' %}

4.自定义inclusion_tag(局部的html代码)

当html页面某一个地方的页面需要传参数才能够动态的渲染出来,并且在多个页面上都需要使用到该局部

@register.inclusion_tag('menu.html',name='mymenu')
def func3(n):
  html = []
  for i in range(n):
    html.append('<li>第%s页</li>' %s)
 return locals()  # 将html传给filename这个页面,然后可以在那个页面上使用

加载自定义文件名
{% load mytag %}
{% mymenu 20%}

filename是作用于一个页面,这个页面可以不是一个完整的页面,只是一部分

image

模板的继承与导入

1.什么是模板的继承

你需要事先在你想要使用的主页面上划定区域做好标记,之后在子页面继承的时候你就可以使用在主页面划定的区域,也就意味着,如果你不划定任何区域,那么你子页面将无法修改主页面内容

2.如何使用模板的继承

1.先在你想要继承的主页面上通过bolck划定你将来可能要改的区域,并做好标记
2.在子页面上继承extends,利用block自动提示选取你想要修改的内容区域标记名称
3.在子页面extends中写你要修改主页面标记区的代码
4.然后就可以让子页面的修改内容渲染到主页面的划定区域上
# 模板页面提前先写好将来可能要替换的内容
    {% block 名字 %}
     """模板内容"""
    {% endblock %}
# 新页面要基于模板页面替换的内容
    {% extends 'html文件名' %}
    {% block 名字 %}
     """子板内容"""
    {% endblock %}
     """一般情况下母板中至少应该有三个区域使得扩展性更高!!!  css content js"""
    {% block css %}
        <style>...</style>
    {% endblock %}

    {% block content %}
        ...
    {% endblock %}

    {% block js %}
        <script>...</script>
    {% endblock %}
    '''子板中还可以使用母板的内容  {{ block.super }} '''

3.模块导入

将页面的某一个局部当成模块的形式
哪个地方需要就可以直接导入使用即可

导入格式
{% include '导入html文件名'  %}

模型层之前期准备

自带的sqlite3数据库对时间字段不敏感 有时候会展示错乱 
所以我们习惯切换成常见的数据库比如MySQL django orm并不会自动帮你创建库 所以需要提前准备好

单独测试django某个功能层

默认不允许单独测试某个py文件 如果想要测试某个py文件可以有两种方式

方式一、在任意空的py文件中准备环境

'''复制mange.py文件的前四行代码 放入一个空白的py文件中 但是不要放入已有的文件中'''
import os

def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djang04.settings')
    import django  # 这个导入文件只能放在这里,放在外面会报错
    django.setup()

    from app01 import models  # 这个导入文件也只能放在这里,放在外面会报错
    print(models.User.objects.filter())


if __name__ == '__main__':
    main()

image

方式二、pycharm提供测试环境

python console命令行测试环境

终端的形式 代码没法保存下来 电话关掉以后 代码就会没有了 只是临时的

image
所有操作就可以直接在test.py文件中执行了
image

ORM常用关键字

create()

创建数据 返回值就是当前创建的数据对象,可以通过点的方式去获取数据对象里面具体的某个字段的值

1.当需要查询数据主键字段值的时候 可以使用pk忽略掉数据字段真正的名字
2.在模型类中可以定义一个__str__方法 便于后续数据对象被打印展示的是查看方便
3.Queryset中如果是列表套对象那么直接for循环和索引取值但是索引不支持负数
4.虽然queryset支持索引但是当queryset没有数据的时候索引会报错 推荐使用first
	 1.create()
        创建数据 返回值就是当前创建的数据对象
        ps:还可以利用类实例化对象然后调用save方法创建
   2.update()
  	 	 更新数据
	 3.delete()
		    删除数据
import os


def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djang04.settings')
    import django
    django.setup()

    from app01 import models
    print(models.User.objects.filter())

    res = models.User.objects.create(name='kevin', age=38)
    print(res)
    user_obj = models.User(name='oscar', age=20)
    user_obj.save()
    # 对象可以通过点的方式取值
    print(res.name)
    print(res.age)
    print(res.join_time)
    # 获取主键
    print(res.uid)
    print(res.pk)

if __name__ == '__main__':
    main()

查找主键的时候有俩中方式:
    1.我们可以通过主键名去使用点的方式去获取
    2.也可以通过点pk得方式去获取
        查找数据对象的主键以后我们创建表的时候可能会创建好多表,那么每个表中的主键名可能不一样,我们在要获取表对象的主键得时候,需要知道表的主键名,使用pk的话它会自动帮我们去找

1.filter()

筛选数据 返回值是一个QuerySet(可以看成是列表套数据对象)
  1.括号内不写查询条件  默认就是查询所有
  2.括号内可以填写条件  并且支持多个 逗号隔开  默认是and关系
  
 res = models.User.objects.filter(name='kevin', age=38)
print(res)   # <QuerySet [<User: 对象:kevin>]>

2.all()

查询所有数据 返回值是一个QuerySet(可以看成是列表套数据对象)

    res = models.User.objects.all()
    print(res)  # <QuerySet [<User: 对象:jason>, <User: 对象:kevin>, <User: 对象:tony>]>

3.first()

获取Queryset中第一个数据对象 如果为空则返回None

    res = models.User.objects.all().first()
    print(res)  # 对象:jason

4.last()

获取Queryset中最后一个数据对象 如果为空则返回None

    res = models.User.objects.all().last()
    print(res)  # 对象:tony

5.get()

直接根据条件查询具体的数据对象 但是条件不存在直接报错 不推荐使用

    res = models.User.objects.get(pk=2)
    print(res)  # 对象:kevin
这个方法与filter方法对比:
    res = models.User.objects.get(pk=2)
    print(res)  # 对象:kevin
    res = models.User.objects.filter(pk=2).first()
    print(res)  # 对象:kevin
    虽然看起来get方法可能更简单一点,但是不推荐使用get方法
        当查询查询条件不存在的时候:
            res = models.User.objects.get(pk=21)
            print(res)  # 直接报错
            res = models.User.objects.filter(pk=21).first()
            print(res)  # None

6.values()

指定查询字段 结果是Queryset(可以看成是列表套字典数据)

    res = models.User.objects.values()
    print(res)   # <QuerySet [{'uid': 1, 'name': 'jason', 'age': 18, 'join_time': datetime.date(2022, 9, 5)}, {'uid': 2, 'name': 'kevin', 'age': 38, 'join_time': datetime.date(2022, 9, 5)}, {'uid': 3, 'name': 'tony', 'age': 19, 'join_time': datetime.date(2022, 9, 5)}]>

7.value_list()

指定查询字段 结果是Queryset(可以看成是列表套元组数据)

8.order_by()

指定字段排序 默认是升序 在字段前加负号则为降序 并且支持多个字段排序

    res = models.User.objects.order_by('age')
    print(res)  # <QuerySet [<User: 对象:jason>, <User: 对象:tony>, <User: 对象:kevin>]>
    res = models.User.objects.order_by('-age')
    print(res)  # <QuerySet [<User: 对象:kevin>, <User: 对象:tony>, <User: 对象:jason>]>

9.count()

统计orm查询之后结果集中得数据格式

    res = models.User.objects.all().count()
    print(res)  # 3

10.distinct()

针对重复的数据进行去重 一定要注意数据对象中的主键

11.exclude()

针对括号内的条件取反进行数据查询QuerySet(可以看成是列表套数据对象)

    res = models.User.objects.exclude(pk=2)
    print(res)  # <QuerySet [<User: 对象:jason>, <User: 对象:tony>]>

12.reveres()

针对已经排了序的结果做颠倒

13.exists()

判断查询结果集是否有数据 返回布尔值 但是几乎不用因为所有数据自带布尔值

14.raw()

执行SQL语句
还可以借助于模块
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("insert into user(name) VALUES ('lisa')")
    cursor.execute("update user set name='lisa' WHERE name='jennie'")
    cursor.execute("delete from user where name='lisa'")
    cursor.execute("select * from user")
    cursor.fetchone()
    cursor.fetchall()
posted @ 2022-12-14 20:07  hugmi男孩  阅读(72)  评论(0)    收藏  举报