查询操作和性能优化
1.基本操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
增
models.Tb1.objects.create(c1
=
'xx'
, c2
=
'oo'
) 增加一条数据,可以接受字典类型数据
*
*
kwargs
obj
=
models.Tb1(c1
=
'xx'
, c2
=
'oo'
)
obj.save()
查
models.Tb1.objects.get(
id
=
123
)
# 获取单条数据,不存在则报错(不建议)
models.Tb1.objects.
all
()
# 获取全部
models.Tb1.objects.
filter
(name
=
'seven'
)
# 获取指定条件的数据
models.Tb1.objects.exclude(name
=
'seven'
)
# 获取指定条件的数据
删
models.Tb1.objects.
filter
(name
=
'seven'
).delete()
# 删除指定条件的数据
改
models.Tb1.objects.
filter
(name
=
'seven'
).update(gender
=
'0'
)
# 将指定条件的数据更新,均支持 **kwargs
obj
=
models.Tb1.objects.get(
id
=
1
)
obj.c1
=
'111'
obj.save()
# 修改单条数据
|
2.Foreign key的使用原因
1
2
3
4
|
约束
节省硬盘
但是多表查询会降低速度,大型程序反而不使用外键,而是用单表(约束的时候,通过代码判断)
|
extra
1
2
3
4
5
|
extra(
self
, select
=
None
, where
=
None
, params
=
None
, tables
=
None
, order_by
=
None
, select_params
=
None
)
Entry.objects.extra(select
=
{
'new_id'
:
"select col from sometable where othercol > %s"
}, select_params
=
(
1
,))
Entry.objects.extra(where
=
[
'headline=%s'
], params
=
[
'Lennon'
])
Entry.objects.extra(where
=
[
"foo='a' OR bar = 'a'"
,
"baz = 'a'"
])
Entry.objects.extra(select
=
{
'new_id'
:
"select id from tb where id > %s"
}, select_params
=
(
1
,), order_by
=
[
'-nid'
])
|
F查询
1
2
|
from
django.db.models
import
F
models.Tb1.objects.update(num
=
F(
'num'
)
+
1
)
|
Q查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
方式一:
Q(nid__gt
=
10
)
Q(nid
=
8
) | Q(nid__gt
=
10
)
Q(Q(nid
=
8
) | Q(nid__gt
=
10
)) & Q(caption
=
'root'
)
方式二:
con
=
Q()
q1
=
Q()
q1.connector
=
'OR'
q1.children.append((
'id'
,
1
))
q1.children.append((
'id'
,
10
))
q1.children.append((
'id'
,
9
))
q2
=
Q()
q2.connector
=
'OR'
q2.children.append((
'c1'
,
1
))
q2.children.append((
'c1'
,
10
))
q2.children.append((
'c1'
,
9
))
con.add(q1,
'AND'
)
con.add(q2,
'AND'
)
models.Tb1.objects.
filter
(con)
|
exclude(self, *args, **kwargs)
1
2
|
# 条件查询
# 条件可以是:参数,字典,Q
|
select_related(self, *fields)
1
2
3
4
|
性能相关:表之间进行join连表操作,一次性获取关联的数据。
model.tb.objects.
all
().select_related()
model.tb.objects.
all
().select_related(
'外键字段'
)
model.tb.objects.
all
().select_related(
'外键字段__外键字段'
)
|
prefetch_related(self, *lookups)
1
2
3
4
|
性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询 在内存中做关联,而不会再做连表查询
# 第一次 获取所有用户表
# 第二次 获取用户类型表where id in (用户表中的查到的所有用户ID)
models.UserInfo.objects.prefetch_related(
'外键字段'
)
|
annotate(self, *args, **kwargs)
1
2
3
4
5
6
7
8
9
10
11
12
|
# 用于实现聚合group by查询
from
django.db.models
import
Count, Avg,
Max
,
Min
,
Sum
v
=
models.UserInfo.objects.values(
'u_id'
).annotate(uid
=
Count(
'u_id'
))
# SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id
v
=
models.UserInfo.objects.values(
'u_id'
).annotate(uid
=
Count(
'u_id'
)).
filter
(uid__gt
=
1
)
# SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
v
=
models.UserInfo.objects.values(
'u_id'
).annotate(uid
=
Count(
'u_id'
,distinct
=
True
)).
filter
(uid__gt
=
1
)
# SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1
|
扫描二维码关注公众号,回复:
4826832 查看本文章
extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
1
2
3
4
5
6
|
# 构造额外的查询条件或者映射,如:子查询
Entry.objects.extra(select
=
{
'new_id'
:
"select col from sometable where othercol > %s"
}, select_params
=
(
1
,))
Entry.objects.extra(where
=
[
'headline=%s'
], params
=
[
'Lennon'
])
Entry.objects.extra(where
=
[
"foo='a' OR bar = 'a'"
,
"baz = 'a'"
])
Entry.objects.extra(select
=
{
'new_id'
:
"select id from tb where id > %s"
}, select_params
=
(
1
,), order_by
=
[
'-nid'
])
|
reverse(self):
1
2
3
|
# 倒序
models.UserInfo.objects.
all
().order_by(
'-nid'
).reverse()
# 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序
|
下面两个 取到的是对象,并且注意 取到的对象可以 获取其他字段(这样会再去查找该字段降低性能
defer(self, *fields):
1
2
3
4
|
models.UserInfo.objects.defer(
'username'
,
'id'
)
或
models.UserInfo.objects.
filter
(...).defer(
'username'
,
'id'
)
# 映射中排除某列数据
|
only(self, *fields):
1
2
3
4
|
# 仅取某个表中的数据
models.UserInfo.objects.only(
'username'
,
'id'
)
或
models.UserInfo.objects.
filter
(...).only(
'username'
,
'id'
)
|