ORM单表增删改查
# 链接资料
# 增
- 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
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
2
3
4
# 改
- update()
# 更新 update() 方法 model对象不能调用更新方法 只能QuerySet调用
models.Student.objects.filter(name='老王').update(age=29)
1
2
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
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
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
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
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
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)