模型表创建 models.py

1
from django.db import models
1
2
3
4
5
6
7
8
9
class Boy(models.Model):
name = models.CharField(max_length=32,null=True)

class Girl(models.Model):
nick = models.CharField(max_length=32,null=True)

class Love(models.Model):
b = models.ForeignKey("Boy",null=True)
g = models.ForeignKey("Girl",null=True)

test4及以后

1
2
3
4
5
class Boy(models.Model):
name = models.CharField(max_length=32,null=True)
g = models.ManyToManyField("Girl",null=True)
class Girl(models.Model):
nick = models.CharField(max_length=32,null=True)
1
2
3
4
5
6
7
8
class UserType(models.Model):
title = models.CharField(max_length=32, null=True)

class UserInfo(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, null=True)
age = models.CharField(max_length=32, null=True)
ut = models.ForeignKey(UserType, null=True) ### 加上一个ud_id

正向查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def test(request):
# 正向查询-------------------------------------------------------
# 在UserInfo表里面查name=威哥的数据 => QuerySet对象
res = models.UserInfo.objects.filter(name='威哥').all()
# <QuerySet [<UserInfo: UserInfo object>]>

res = models.UserInfo.objects.all()
# <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>

res = models.UserInfo.objects.all().values()
# <QuerySet [{'id': 1, 'name': '王伟', 'age': '18', 'ut_id': 1}, {'id': 2, 'name': '威哥', 'age': '19', 'ut_id': 2}, {'id': 3, 'name': '三上', 'age': '20', 'ut_id': 3}]>

res = models.UserInfo.objects.all()
for item in res:
print(item.name,item.age,item.ut_id)
# 王伟 18 1
# 威哥 19 2
# 三上 20 3

反向查询

反向查询—-obj.userinfo_set.all()

1
2
3
4
5
6
7
8
9
10
11
12
13
# 根据UserType查其下各部门的人
res = models.UserType.objects.all().values()
# <QuerySet [{'id': 1, 'title': '技术部'}, {'id': 2, 'title': '公关部'}, {'id': 3, 'title': '宣传部'}]>
res = models.UserType.objects.all()
for obj in res:
print(
obj.id,
obj.title,
obj.userinfo_set.all()
)
# 1 技术部 <QuerySet [<UserInfo: UserInfo object>]>
# 2 公关部 <QuerySet [<UserInfo: UserInfo object>]>
# 3 宣传部 <QuerySet [<UserInfo: UserInfo object>]>

反向查询——神奇的双下划线(跨表查询)

1
2
3
# 通过UserInfo表的name查询Usertype表中对应的部门名称
res = models.UserInfo.objects.values('name', "ut__title")
# <QuerySet [{'name': '王伟', 'ut__title': '技术部'}, {'name': '威哥', 'ut__title': '公关部'}, {'name': '三上', 'ut__title': '宣传部'}]>

多对多查询的三种实现方式

1(1). 查询和xx约会的女生

1
2
3
4
5
# 使用Boy/Girl/Love三张表 测试多对多
res = models.Boy.objects.filter(name='胡心亚').first() # 获取胡心亚对象
love_list = res.love_set.all() # 相亲记录
for obj in love_list:
print(obj.g.nick) # Love的条目对象通过外键连接到Girl表找到对应的nickname

1(2). 查询和xx约会的女生

1
2
3
4
5
6
7
8
9
# b__name双下划线跨表找到的对端表字段属性
res = models.Love.objects.filter(b__name='胡心亚').all()
# <QuerySet [<Love: Love object>, <Love: Love object>, <Love: Love object>]>
for obj in res:
print(obj.g.nick)
# 波多野结衣
# 三上悠亚
# 宇都宫紫苑
# print(res)

1(3).查询xx和约会的女生

1
2
res = models.Love.objects.filter(b__name='胡心亚').values('g__nick')
# <QuerySet [{'g__nick': '波多野结衣'}, {'g__nick': '三上悠亚'}, {'g__nick': '宇都宫紫苑'}]>

添加 (create与add)

1
2
3
4
5
6
7
8
9
10
def test4(request):
# 用第三张表(虚拟表)
# 此时的表模型如下(不同之前的test表模型)
class Boy(models.Model):
name = models.CharField(max_length=32,null=True)
g = models.ForeignKey("Girl",null=True)
class Girl(models.Model):
nick = models.CharField(max_length=32,null=True)

# 改完表之后记得 makemigrations 和 migrate

create

1
2
# 1(1)添加数据---不选对象----------------------------------------------
models.Love.objects.create(b_id=1,g_id=3) # 在Love表中添加一条数据

add

1
2
3
4
5
6
7
8
# 1(2)添加数据---选择对象-------------------------------------------------
obj = models.Boy.objects.filter(name='小何').first() # 选出小何
obj.g.add(3) # app01_boy_g 内部成功添加了id=1,b_id=5,g_id=3的条目
obj.g.add(*[1,2,3])
# 重复添加 并不会重复出现在数据库中 ManyToManyField内部优化
# 1 5 3
# 2 5 1
# 3 5 2

重置 (set)

1
2
3
# 2 重置
obj.g.set([4])
# 所有的条目消失,只有一个相亲女序号为4的出现在boy_g表中

查询 (filter)

1
2
3
4
5
6
7
8
9
10
11
# 3 查询
# 把小何的所有相亲对象名字打印出来
obj = models.Boy.objects.filter(name='小何').first() # 选出小何
res = obj.g.all()
print(res)
# <QuerySet [<Girl: Girl object>, <Girl: Girl object>, <Girl: Girl object>]>
for obj in res:
print(obj.nick)
# 波多野结衣
# 三上悠亚
# 宇都宫紫苑

查询条件控制

in

1
2
3
4
5
6
7
8
9
10
11
12
def test5(request):
# 类比原生SQL语句的各查询组件
# in 、not in、like、between……and……、limit、order by、group by
## 1. in id__in与神奇的双下划线是不一样的
res = models.UserInfo.objects.filter(id__in=[1,2,3])
print(res)
<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
for obj in res:
print(obj.name)
# 杰哥
# 阿伟
# 小何

not in exclude

1
2
3
4
5
6
7
8
9
10
## 2. not in    exclude vt. 排除;
res = models.UserInfo.objects.exclude(id__in=[1,2,3])
print(res)
# <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
for obj in res:
print(obj.name)
# 伟伟
# 尖尖角
# 佳伟
# 嘎嘎

like startswith istartswith endswith iendswith contains

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## 3 like
res = models.UserInfo.objects.filter(name__startswith="V")
for obj in res:
print(obj.name)
# Venti
### startswith: 以 某单词开头
### istartswith : ignore (忽略) 以 某单词开头 忽略大小写
res = models.UserInfo.objects.filter(name__istartswith="v")
for obj in res:
print(obj.name)
# Venti

## endswith : 以 某个单词结尾
## iendswith: ignore (忽略) 以 某单词结尾 忽略大小写
res = models.UserInfo.objects.filter(name__endswith='ze')
res = models.UserInfo.objects.filter(name__iendswith='ze')

### contains : 包含某一个单词
### icontains: 包含某一个单词 不区分大小写
res = models.UserInfo.objects.filter(name__contains='ze')

xx__range

1
2
3
4
5
6
7
8
9
### 4. between.. and..
# res = models.UserInfo.objects.filter(id__range=[1,5])
# for obj in res:
# print(obj.name)
# 杰哥
# 阿伟
# 小何
# 伟伟
# 尖尖角

limit (直接用切片符)

1
2
3
4
5
6
7
8
9
10
11
12
### 5. limit 10, 20
# models.UserInfo.objects.all()[开始位置:结束位置]
res = models.UserInfo.objects.all()[0:10]
# for obj in res:
# print(obj.name)
# 阿伟
# 小何
# 伟伟
# 尖尖角
# 佳伟
# 嘎嘎
# Venti

order by (asc/desc)

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
### 6. order by age asc, name desc
res = models.UserInfo.objects.all().order_by('id') ## 默认升序
for obj in res:
print(obj.id)
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
### 前面加一个 ‘-’ 代表 降序
res = models.UserInfo.objects.all().order_by('-id','name')
for obj in res:
print(obj.id)
# 8
# 7
# 6
# 5
# 4
# 3
# 2
# 1
# print(res.query)

having

1
2
# having是嵌套查询的限制条件,直接在循环嵌套后补添加filter()即可
res = models.UserInfo.objects.values('name').annotate(xx=Count('id')).filter(xx_lt=3)

group by

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
### 7. group by
from django.db.models import Count, Max, Min, Sum
# annotate vi. 注释
# values 相当于 group by
res = models.UserInfo.objects.values('name').annotate(bieming=Count('id'))
for obj in res:
print(obj)
# {'name': 'Venti', 'bieming': 1}
# {'name': '伟伟', 'bieming': 1}
# {'name': '佳伟', 'bieming': 1}
# {'name': '嘎嘎', 'bieming': 1}
# {'name': '小何', 'bieming': 1}
# {'name': '尖尖角', 'bieming': 1}
# {'name': '杰哥', 'bieming': 1}
# {'name': '阿伟', 'bieming': 1}

print(res.query) # 查看SQL原语

# SELECT "app01_userinfo"."name", COUNT("app01_userinfo"."id") AS "bieming"
# FROM "app01_userinfo"
# GROUP BY "app01_userinfo"."name"

only

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#### 8. only: 只取某一个列的值
## SELECT "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age" FROM "app01_userinfo"
res = models.UserInfo.objects.only('name', 'age').all()
print(res) ## <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
for obj in res:
print(obj.name,obj.age)
# 杰哥 18
# 阿伟 19
# 小何 20
# 伟伟 22
# 尖尖角 16
# 佳伟 22
# 嘎嘎 33
# Venti 44

defer (排除)

1
2
3
4
### 9. defer: 除了这几列之外的所有列的值 deferred v. 推迟
### SELECT "app01_userinfo"."id", "app01_userinfo"."ut_id" FROM "app01_userinfo"
res = models.UserInfo.objects.defer('id','name', 'age').all()
print(res.query)

using (数据库选择)

1
2
### 10.using: 想要使用哪个数据库, 就将这个数据库的配置名称写到using中
models.UserInfo.objects.all().using("xxxx")

count(数据条目统计)

1
2
3
### 11. 表中总共多少条数据
res = models.UserInfo.objects.count()
# print(res)

first

1
2
3
### 12. 第一条数据
res = models.UserInfo.objects.first()
# print(res)

last

1
2
## 13.最后一条数据
res = models.UserInfo.objects.last()

gt lt gte lte

1
2
3
4
5
## 14.gt lt
res = models.UserInfo.objects.filter(id__gt=3)
res = models.UserInfo.objects.filter(id__gte=3)
res = models.UserInfo.objects.filter(id__lt=3)
res = models.UserInfo.objects.filter(id__lte=3)

and

1
2
3
### 15. and操作
res = models.UserInfo.objects.filter(id=1, name='zekai')
# print(res.query)

Q

1
2
3
4
### 16.or操作
from django.db.models import Q
res = models.UserInfo.objects.filter( Q(Q(id=1) | Q(name='zekai')) & Q(name='xxxx') )
# print(res.query)

F

1
2
3
### 17. 在原来的基础上更新值 全选加减乘除乘方
from django.db.models import F
models.UserInfo.objects.update(age = F('age') + 1)

原生SQL connection

1
2
3
4
5
6
7
## 18。原生sql
from django.db import connection
cursor = connection.cursor()
cursor.execute("select * from app01_userinfo where id=%s", [1,])
res = cursor.fetchall()
res = cursor.fetchone()
# # print(res)

原生SQL raw

1
2
## 19. 原生sql
models.UserInfo.objects.raw('select * from app01_userinfo')

删除 delete

1
2
3
## 20. 删除
models.UserType.objects.filter(id=2).delete()
return HttpResponse('ok')

联级删除

1
2
3
4
5
6
ps:
级联删除
ForeignKey(on_delete=models.CASCADE)

CASCADE: 级联删除 默认
SET_NULL: 取消级联删除

一对一

OneToOne

UserInfo是母表(不可在被分割)
Salary是子表(可被分割)

正向查询 (子表查母表)

对应不同的Django版本有不同的写法
1.11.22: res.us.name ——对象.外键.字段名
1.11.10: res.母表名称小写.name —– 对象.母表名称小写.字段名
.

1
2
res = models.UserInfo.objects.filter(name='Venti').first()
print(res.salary.money)

反向查询 (母表查子表)

1
2
res = models.UserInfo.objects.filter(name='Venti').first()
print(res.salary.money)