模板层语法、模板层之标签、模板的继承与导入、模型层之ORM常见关键字

一、模板层语法

1.模板语法的传值

urls代码:
path('modal/', views.modal)

views代码:
def modal(request):
    name = 'jason'
    return  render(request, 'modal.html', {'name':name})

指名道姓传参 不浪费资源
html代码:
<body>
    {{ name }}
    {{ age }}
    {{ gender }}
</body>

urls代码:
path('modal/', views.modal)

views代码:
def modal(request):
    name = 'jason'
    age = 18
    gender = 'female'
    return render(request, 'modal.html', locals())  # 将函数体里局部空间里所有的名字全部传入给前面的那个页面

将整个局部名称空间中的名字去全部传入简单快捷

2.模板语法传值特性

    1.基本数据类型正常展示
    2.文件对象也可以展示并调用方法
    3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
    4.类名也会自动加括号调用
    5.对象则不会	
	 ps:总结针对可以加括号调用的名字模板语法都会自动加括号调用

3.模板语法传值的范围

基本数据类型直接传值使用
views代码:
def modal(request):
    i = 123
    f = 13.4
    s = 'study work hard'
    d = {'name': 'Tony', 'pwd': 123}
    t = (11, 22, 33)
    se = {11, 22, 33}
    b = True
    return render(request,'modal.html',locals())
html代码:
     <p>{{ i }}</p>
      <p>{{ f }}</p>
      <p>{{ s }}</p>
      <p>{{ l }}</p>
      <p>{{ d }}</p>
      <p>{{ t }}</p>
      <p>{{ se }}</p>
      <p>{{ b }}</p>
函数名的传递会自动加上括号执行并将返回值展示到页面上,模板语法时不支持有参函数的
def modal(request):
    def func():
        print('函数')
        return '从这里才能传值过去哦'
    return render(request,'modal.html',locals())
 <p>{{ func }}</p>

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

1.模板语法过滤器
过滤器就类似于模板语法的内置方法
模板语法提供了一些内置方法,以助于快速的处理数据(过滤器最多只能有两个参数)
2.基本语法
{{变量|过滤器:参数}}
过滤器:会自动将竖杠左侧的变量当做第一个参数交给过滤器处理,右侧的当做第二个参数。
'''
    django模板语法中的符号就两个 一个{{}} 一个{%%}
	需要使用数据的时候 {{}}
	需要使用方法的时候 {%%}
''' 
    <p>统计长度:{{ s|length }}</p>
    # 统计长度:15

    <p>加法运算:{{ i|add:123 }}、加法运算:{{ s|add:'heiheihei' }}</p>
    # 加法运算:246、字符串加法运算:study work hard +every day

    <p>日期转换:{{ s|date:'Y-m-d H:i:s' }}</p>

    <p>文件大小:{{ file_size|filesizeformat }}</p>
    # 文件大小:31.1 KB

    <p>数据切片:{{ l|slice:'0:10' }}</p>
    # 切片操作(支持步长)

    <p>字符截取(三个点算一个):{{ s1|truncatechars:6 }}</p>
    # 字符截取(包含三个点):模板语法提供...

    <p>单词截取(空格):{{ s1|truncatewords:6 }}</p>
    # 单词截取(不包含三个点 按照空格切):my name is objk my age is 18 and ...

    <p>语法转义:{{ script_tag }}</p>
    # <h1>今晚吃了好多好吃的</h1>(是不会识别前端标签的)

    <p>语法转义:{{ script_tag|safe }}</p>
    # 今晚吃了好多好吃的

    # 如果不转移的话,那么无法识别前端标签,那么以下这种功能的情况就没有办法实现
    <p>语法转义:{{ script_tag1|safe }}</p>
    script_tag1 = '<script>alert(666)</script>'

    # 也可以使用后端转
    from django.utils.safestring import mark_safe
    script_tag2 = '<script>alert(666)</script>'
    res = mark_safe(script_tag2)
    ps:有时候html页面上的数据不一定非要在html页面上编写了 也可以后端写好传入

二、模板层之标签(类似于Python流程控制)

1.if判断

{% if 条件1(可以自己写也可以用传递过来的数据) %}
        <p>xxxxx</p>
{% elif 条件2(可以自己写也可以用传递过来的数据) %}
        <p>xxxxxx</p>
{% else %}
        <p>没多少时间了!</p>
{% endif %}

eg:
{% if b %}
	<p>今天又是周三了,好好学习啊</p>
{% elif n %}
	<p>加油加油</p>
{% else %}
	<p>相信自己,可以的</p>
{% endif %}

2.for循环

forloop模板语法自带的变量名
{% for k in t1 %}
        {% if forloop.first %}
            <p>这是我的第一次循环{{ k }}</p>
        {% elif forloop.last %}
            <p>这是我的最后一次循环{{ k }}</p>
        {% else %}
            <p>这是中间循环{{ k }}</p>
        {% endif %}
        
        {% empty %}
            <p>empty专门用来判断空的,传的是空的无法循环取值(空字符串,空列表,空字典)</p>
{% endfor %}

eg:
{% for k in t1 %}
	{% if forloop.first %}
		<p>这是第一次循环</p>
	{% elif forloop.last %}
		<p>这是最后一次循环</p>
	{% else %}
		<p>{{ i }}</p>
	{% endif %}
	{% empty %}
		<p>empty专门用来判断空的,传的是空的无法循环取值(空字符串,空列表,空字典)</p>
{% endfor %}

image

3.with语法起别名

{% with d.hobby.3.a1 as n %}
	<p>{{ n }}</p>
    在with语法内可以通过as后面得别名快速使用前面非常复杂获取数据的方式
	<p>{{ d.hobby.3.a1 }}</p>
{% endwith %}
ps:
可以通过as后面得别名快速的使用前面非常复杂获取数据的方式
密码规范:只能with代码块的范围之内才能使用别名

三、自定义过滤器、标签及inclusion_tag

1.自定义一些模板语法 先完成下列的三步走战略


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

2.自定义过滤器filter,最多有两个参数

from django import template
register = template.Library()

# 自定义过滤器,最大只能接收两个参数
# 参数     过滤器     过滤器名字
@register.filter(name='myfilter')
def my_add(a,b):
    return a + b

{%  load first %}
<p>{{ i|myfilter:1 }}</p>

3.自定义标签(函数)

# 参数    标签(函数)标签(函数)名字
@register.simple_tag(name='nt')
def my_add(a,b,c,d):
    return a + b + c + d

{%  load first %}
{% nt 1 2 3 4 %}

4.自定义inclusion_tag页面

# 自定义inclusion_tag(局部的html代码)
@register.inclusion_tag('menu.html',name='mymenu')
def func3(n):
    html = []
    for i in range(n):
        html.append('<li>第%s页</li>'%i)
    return locals()      # 将html传给name的页面,在哪个页面上使用

{% load mytags %}
{% mymenu 20 %}

四、模板的继承与导入

1.模板的继承

模板继承是 Django 模板语言中最强大的部分。模板继承使你可以构建基本的“骨架”模板,模板继承大大提高了代码的可重用性,减轻开发人员的工作量。

2.任何使用模板的继承

1.在模板的使用block规划子板以后要修改的区域,并做好标记
2.在子页面上继承extend,利用block自动选取你想要修改的内容区域标记名称
3.在子页面extend中写您想要修改主页面标记区的代码
4.然后让子页面的修改内容渲染到主页面的规定区域上
# 模板页面提前写好将要替换的内容
{%  block  区域名称 %}
{%  endblock %}

# 子板继承模板
{%   extend  'html文件'%}
{%  block  区域名称 %}
    '''子板内容'''
{%  endblock %}
{%  block  css %}
    '''子板内容'''
{%  endblock %}
{%  block  js %}
    '''子板内容'''
{%  endblock %}
'''子板可以继续使用模(母)板的内容'''

3.模板的导入

将某个html的部分提前写好 之后很多html页面都想使用就可以导入
 		{% include 'myform.html' %}

五、表查询数据准备及测试环境搭建

1.djaingo自带一个sqlite3小型数据库

自带的sqlite3数据库对于时间字段不敏感,有时候会展示错乱
sqlite3是pycharm自带的数据库,不用额外安装模块,操作简单
python + mysql = SQLite

2.djiango切换到MySQL数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day05',
        'USER': 'root',
        'PASSWORD': '123',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'CHARSET':'utf8'
    }
}

3.定义模型类

from django.db import models

# Create your models here.

class User(models.Model):
    name = models.CharField(max_length=32,verbose_name='用户名')
    age = models.IntegerField(verbose_name='年龄')
    register_time = models.DateTimeField(verbose_name='注册时间',auto_now_add=True)


    def __str__(self):
        return f'用户对象{self.name}'
    
'''
针对时间字段有两个重要的参数:
     auto_now:每次操作数据都会自动更新当前时间
     auto_now_add:创建数据自动获取当前的时间,后续不人为操作的情况下不会更新
'''

4.执行数据库迁移命令(模型类>>>表)

python mange.py makemigrations

python mange.py migrate

5.模型层测试环境准备

方式一:
'''复制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()
方式二:
python console命令行测试环境

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

六、ORM常见关键字

1.create()

    创建数据并直接获取当前创建的数据对象
    res = models.User.objects.create(name='jason',age=18)
     res = models.User.objects.create(name='jia',age=17)
     res = models.User.objects.create(name='wei',age=28)
     res = models.User.objects.create(name='xin',age=38)
     res = models.User.objects.create(name='roy',age=48)
     res = models.User.objects.create(name='jackson',age=58)

2.filter()

  根据条件筛选数据,结果是QuerySet [数据对象1,数据对象2]
  res = models.User.objects.filter()
  res = models.User.objects.filter(name='jason')

3.first() last()

QuerySet支持索引取值但是只支持正数 并且orm不建议你使用索引
 res = models.User.objects.filter()[1]
 res = models.User.objects.filter(pk=100)[0]  # 数据不存在索引取值会报错
 res = models.User.objects.filter(pk=100).first()  # 数据不存在不会报错而是返回None
 res = models.User.objects.filter().last()  # 数据不存在不会报错而是返回None

4.update()

 models.User.objects.filter().update()     批量更新
 models.User.objects.filter(id=1).update() 单个更新

5.delete()

 models.User.objects.filter().delete()     批量删除
 models.User.objects.filter(id=1).delete() 单个删除

6.all()

models.User.objects.filter().all()     查询所有数据
结果是QuerySet [数据对象1,数据对象2]

7.values()

res = models.User.objects.all().values('name')  
res = models.User.objects.filter().values('name')
res = models.User.objects.value('name')
结果是QuerySet  [{},{},{}]

8.values_list()

res = models.User.objects.values_list('name')
根据指定字段获取数据  结果是QuerySet [(),(),(),()]

9.distinct()

res = models.User.objects.values('name','age').distinct()
去重 数据一定要一模一样才可以 如果有主键肯定不行

10.order_by()

models.User.objects.filter().all().order_by()
根据指定条件排序  默认是升序 字段前面加负号就是降序

11.get()

models.User.objects.get(pk=1)
根据条件筛选数据并直接获取到数据对象  一旦条件不存在会直接报错 不建议使用

12.exclude()

res = models.User.objects.exclude(pk=1)
取反操作
#   颠倒顺序(被操作的对象必须是已经排过序的才可以)
    # res = models.User.objects.all()
    # res = models.User.objects.all().order_by('age')
    # res1 = models.User.objects.all().order_by('age').reverse()
    # print(res, res1)
    # 14.count()  统计结果集中数据的个数
    # res = models.User.objects.all().count()
    # print(res)
    # 15.exists()  判断结果集中是否含有数据 如果有则返回True 没有则返回False
    res = models.User.objects.all().exists()
    print(res)
    res1 = models.User.objects.filter(pk=100).exists()
    print(res1)

13.reverse()

颠倒顺序(被操作的对象必须是已经排过序的才可以)
res = models.User.objects.all()
res = models.User.objects.all().order_by('age')
res1 = models.User.objects.all().order_by('age').reverse()
 print(res, res1)

14.count()

统计结果集中数据的个数
res = models.User.objects.all().count()

15.exists()

判断结果集中是否含有数据 如果有则返回True 没有则返回False
res = models.User.objects.all().exists()
print(res)
res1 = models.User.objects.filter(pk=100).exists()
print(res1)
返回QuerySet对象的方法有
all()

filter()

exclude()

order_by()

reverse()

distinct()
特殊的QuerySet
values()       返回一个可迭代的字典序列

values_list() 返回一个可迭代的元祖序列
返回具体对象的
exists()

返回数字的方法

count()