查询操作和性能优化
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 |
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' ) |