yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • python基础

  • python高级

  • python模块

  • python设计模式

  • python数据结构与算法

  • django

    • web基础

    • django框架脑图(!必看)

    • django简介
    • MVC及MTV设计模式
    • 搭建django项目环境
    • url路由
    • view视图
    • 模板语法
    • 模型ORM

      • 模型ORM简介
      • 模型和字段(1)
      • 模型和字段(2)
      • 多对多中间表详解
      • 模型的继承
      • 模型的元数据Meta
      • ORM单表增删改查
        • 链接资料
          • 增
          • 删
          • 改
          • 查
          • 查询接口
          • 必会必知13条
          • 基于双下划线的模糊查询
          • 单表的双下划线
      • ORM多表增删改查
      • ORM中的事务和锁
      • 验证器
    • 中间件
    • cookie,session
    • Form和modelform校验器、同源和跨域问题
    • 文件处理

    • django-websocket

    • django测试

    • django-项目

  • django-DRF

  • flask

  • 自己设计开源pip包

  • 自己设计开源项目

  • python小示例

  • python面试题

  • python
  • django
  • 模型ORM
YiZhang-You
2023-05-18
目录

ORM单表增删改查

# 链接资料

  1. 官网

    文档 (opens new window)

  2. 刘江

    https://www.liujiangblog.com/course/django/129 (opens new window)

# 增

  • save()
  • create()
  • bulk_create()
  • update_or_create()
# 创建记录方式1
    student_obj = models.Student(
        name='老王',
        age=19,
    )
    student_obj.save() # 刷到表里
# 创建记录方式2
    new_obj = models.Student.objects.create(name='小李', age=15) # Student object -- models对象
    print(new_obj.name)
    print(new_obj.age)

# 创建方式3
    批量创建
    objs = []
    for i in range(20):
        obj = models.Student(
            name='xiangxi%s' % i,
            age=10 + i,
        )
        objs.append(obj)

    models.Student.objects.bulk_create(objs)

# 创建方法4
    update_or_create() 有就更新 没有就创建、
    models.Student.objects.update_or_create(
        name='老王2',
        defaults={
            'age':48,
        }
    )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 删

  • delete()
# 删除 delete  queryset 和 model 都可以调用
models.Student.objects.get(id=2).delete()  # model对象调用delete方法
models.Student.objects.filter(name='小小').delete()
models.Student.objects.all().delete()  # 删除所有
1
2
3
4

# 改

  • update()
# 更新 update() 方法  model对象不能调用更新方法 只能QuerySet调用
models.Student.objects.filter(name='老王').update(age=29)
1
2

# 查

  • .all() 查询所有,返回querySet集合(类似于列表)
  • .filter() 查不到返回一个空集合不报错,返回QuerySet
  • .get() 有且只有1个结果(没有或者多于一个结果报错),返回model对象
# 简单查询
all_obj = models.Student.objects.all()  # 查询所有
print(all_obj)  # <QuerySet [<Student: Student object>, <Student: Student object>]>--类似于列表 -- QuerySet集合
for i in all_obj:
    print(i.name)

# 条件查询  .filter() 返回的也是QuerySet集合,查不到返回一个空集合,不报错
objs = models.Student.objects.filter(id=2)
objs = models.Student.objects.filter(name='老王')
print(objs)

# 条件查询  get() 返回的是model对象,而且get方法有且必须有1个结果
obj = models.Student.objects.get(id=1)
print(obj)  # 老王
obj = models.Student.objects.get(name='小小')  # 报错1,查询结果多于1个
get() returned more than one Student -- it returned 2!
obj = models.Student.objects.get(name='大大')  # 报错2 没有查询到任何内容
# Student matching query does not exist.
print(obj)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 查询接口

<1> all():                  查询所有结果,结果是queryset类型

<2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象,结果也是queryset类型 Book.objects.filter(title='linux',price=100) #里面的多个条件用逗号分开,并且这几个条件必须都成立,是and的关系,or关系的我们后面再学,直接在这里写是搞不定or的
      models.Student.objects.filter(id=7, name='xiangxi0').update(
            name='小小妹妹',
            age=18,
        )

<3> get(**kwargs):          返回与所给筛选条件相匹配的对象,不是queryset类型,是行记录对象,返回结果有且只有一个,
                            如果符合筛选条件的对象超过一个或者没有都会抛出错误。捕获异常try。  Book.objects.get(id=1)

<4> exclude(**kwargs):      排除的意思,它包含了与所给筛选条件不匹配的对象,没有不等于的操作昂,用这个exclude,返回值是queryset类型 Book.objects.exclude(id=6),返回id不等于6的所有的对象,或者在queryset基础上调用,Book.objects.all().exclude(id=6)

<5> order_by(*field):       queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型
                  models.Book.objects.all().order_by('price','id') #直接写price,默认是按照price升序排列,按照字段降序排列,就写个负号就行了order_by('-price'),order_by('price','id')是多条件排序,按照price进行升序,price相同的数据,按照id进行升序

<6> reverse():              queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型

<7> count():                queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量。

<8> first():                queryset类型的数据来调用,返回第一条记录 Book.objects.all()[0] = Book.objects.all().first(),得到的都是model对象,不是queryset

<9> last():                queryset类型的数据来调用,返回最后一条记录

<10> exists():              queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False
                   空的queryset类型数据也有布尔值True和False,但是一般不用它来判断数据库里面是不是有数据,如果有大量的数据,你用它来判断,那么就需要查询出所有的数据,效率太差了,用count或者exits
                 例:all_books = models.Book.objects.all().exists() #翻译成的sql是SELECT (1) AS `a` FROM `app01_book` LIMIT 1,就是通过limit 1,取一条来看看是不是有数据

<11> values(*field):        用的比较多,queryset类型的数据来调用,返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                            model的实例化对象,而是一个可迭代的字典序列,只要是返回的queryset类型,就可以继续链式调用queryset类型的其他的查找方法,其他方法也是一样的。
<12> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

<13> distinct():            values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复纪录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 必会必知13条

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")

import django

django.setup()

from app01 import models

#  all 查询所有的数据  QuerySet  对象列表  【对象,对象】
ret = models.Person.objects.all()  # 光查询这个的话是先调用的__repr__

#  get 获取一个有且唯一的数据  对象  没有或者多个就报错(其实就是Id为1的)
ret = models.Person.objects.get(pk=1)  # 有具体查询的就是直接调用的__str__

#  filter 获取满足条件的数据  对象列表  【对象,对象】 没有会返回一个空的列表
ret = models.Person.objects.filter(pk=1)

#  order_by 排序 默认升序 如果字段前加-号,就变成降序排序 【可以多字段排序】
ret = models.Person.objects.all().order_by("-age", "pid")

#  reverse 对已经排序的对象列表进行翻转
ret = models.Person.objects.all().order_by("pid").reverse()

#  values 不指定字段  获取数据所有的字段和值 QuerySet [{},{},{}] 字典
#  指定字段 获取数据指定的字段名和值 QuerySet [{"pid":5,"name":111}] 字典
ret = models.Person.objects.all().values("pid", "name")

#  values_list 不指定字段 获取数据所有的值 QuerySet [(),()] 元组
#  指定字段 获取数据指定字段的值 QuerySet  [('111', 5), ('1111', 3)]
ret = models.Person.objects.all().values_list("name", "pid")

#  distinct 去重(去除age一样的)
ret = models.Person.objects.values("age").distinct()

#  count 计数
ret = models.Person.objects.all().count()

#  first 获取第一个元素
ret = models.Person.objects.all().first()

#  last 获取最后一个元素
ret = models.Person.objects.all().last()

#  exists 判断是否有结果 True,False
ret = models.Person.objects.filter(pk=2).exists()
print(ret)

"""
返回对象列表
all
filter
exclude   取反
order_by
reverse
values      [{},{}]
values_list     [(),()]
distinct

返回对象
get
first
last

返回数字
count

返回布尔值
exists
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

# 基于双下划线的模糊查询

  • in 之中
  • gt 大于等于
  • lt 小于等于
  • range 区间
  • contains / icontains 包含
  • startswidth 开头
  • year 日期 (查找日期的时候要注意时区的问题,在settings.py中改USE_TZ为FALSE)
Book.objects.filter(price__in=[100,200,300]) #price值等于这三个里面的任意一个的对象
Book.objects.filter(price__gt=100)  #大于,大于等于是price__gte=100,别写price>100,这种参数不支持
Book.objects.filter(price__lt=100)
Book.objects.filter(price__range=[100,200])  #sql的between and,大于等于100,小于等于200
Book.objects.filter(title__contains="python")  #title值中包含python的
Book.objects.filter(title__icontains="python") #不区分大小写
Book.objects.filter(title__startswith="py") #以什么开头,istartswith  不区分大小写
Book.objects.filter(pub_date__year=2012)
# 日期查询
# all_books = models.Book.objects.filter(pub_date__year=2012) #找2012年的所有书籍
    # all_books = models.Book.objects.filter(pub_date__year__gt=2012)#找大于2012年的所有书籍
    all_books = models.Book.objects.filter(pub_date__year=2019,pub_date__month=2)#找2019年月份的所有书籍,如果明明有结果,你却查不出结果,是因为mysql数据库的时区和咱们django的时区不同导致的,了解一下就行了,你需要做的就是将django中的settings配置文件里面的USE_TZ = True改为False,就可以查到结果了,以后这个值就改为False,而且就是因为咱们用的mysql数据库才会有这个问题,其他数据库没有这个问题。
1
2
3
4
5
6
7
8
9
10
11
12

# 单表的双下划线

ret = models.Person.objects.filter(pid__lt=5)  # 字段__条件 = less than pid小于5的
ret = models.Person.objects.filter(pid__gt=5)  # 字段__条件 = less than pid大于5的
ret = models.Person.objects.filter(pid__lte=5)  # 字段__条件 = less than equal pid小于等于5的
ret = models.Person.objects.filter(pid__gte=5)  # 字段__条件 = less than pid equal 大于等于5的

ret = models.Person.objects.filter(pid__range=[1, 6])  # 范围 在1到6之间的 包括1和6
ret = models.Person.objects.filter(pid__in=[1, 3, 11])  # 成员判断 pid中有没有 为1,3,11的

ret = models.Person.objects.filter(name__contains="李小小")  # 表示name里面有没有包含"李小小"的
ret = models.Person.objects.filter(name__icontains="a")  # 表示name里面有没有包含"a/A"的 加i了忽略大小写

ret = models.Person.objects.filter(name__startswith="李")  # 表示name以“李”开头的
ret = models.Person.objects.filter(name__istartswith="a")  # 表示name以“a/A”开头的,忽略大小写

ret = models.Person.objects.filter(name__endswith="小")  # 表示name以“小”结尾的
ret = models.Person.objects.filter(name__iendswith="a")  # 表示name以“a/A”结尾的,忽略大小写

ret = models.Person.objects.filter(birth__year="2020")  # 表示birth里面年为2020的
# ret = models.Person.objects.filter(birth__month="2")  # 表示birth里面月为2的
# ret = models.Person.objects.filter(birth__day="21")  # 表示birth里面日期为21的

ret = models.Person.objects.filter(birth__contains="-10-")  # 表示月份为10的

ret = models.Person.objects.filter(name__isnull=False)  # 输出name字段不为空的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
编辑 (opens new window)
模型的元数据Meta
ORM多表增删改查

← 模型的元数据Meta ORM多表增删改查→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式