1.ORM连表查询
1.1 创建表UserType 和 UserInfo
class UserType(models.Model): title = models.CharField(max_length=56) class UserInfo(models.Model): name = models.CharField(max_length=64) age = models.IntegerField() ut = models.ForeignKey('UserType')
1.2 给每个表创建数据
def test(request): # 创建UserType表的数据 models.UserType.objects.create(title='三好学生') models.UserType.objects.create(title='优秀学员') models.UserType.objects.create(title='文艺多才') # 创建UserInfo表的数,并与UserType表进行关联 models.UserInfo.objects.create(name='张三',age=15,ut_id=1) models.UserInfo.objects.create(name='李四',age=17,ut_id=2) models.UserInfo.objects.create(name='王五',age=16,ut_id=3) models.UserInfo.objects.create(name='马六',age=14,ut_id=1) models.UserInfo.objects.create(name='苟七',age=16,ut_id=3) models.UserInfo.objects.create(name='赵八',age=15,ut_id=2) return HttpResponse('...')
1.3 UserInfo关联UserType进行查询(正向操作):
1.3.1 取全部内容
obj = models.UserInfo.objects.all() 获取全部内容 for ret in obj: print(ret.id,ret.name,ret.age,ret.ut_id,ret.ut.title) ret.ut.title表示取UserType里每个用户相关联的内容
1.3.2 取第一行内容
obj = models.UserInfo.objects.all().first() print(obj.id,obj.name,obj.age,obj.ut_id,obj.ut.title) 只取第一行 不用for循环
1.3.3 字典取法
obj = models.UserInfo.objects.values('id','name','age','ut__title') for res in obj: print(res['id'],res['name'],res['age'],res['ut__title'],)
1.3.4 元组取法
obj = models.UserInfo.objects.values_list('id', 'name', 'age', 'ut__title') for res in obj: print(res[0], res[1], res[2], res[3], )
1.4 UserType关联UserInfo (反向操作)
1.4.1 取全部内容
obj = models.UserType.objects.all() for ret in obj: for res in ret.userinfo_set.all(): print(ret.id,ret.title,res.id,res.name,res.age,res.ut_id)
1.4.2 取第一行内容
obj = models.UserType.objects.all().first() for res in obj.userinfo_set.all(): print(obj.id,obj.title,res.id,res.name,res.age)
1.4.3 字典取法
obj = models.UserType.objects.values('id','title','userinfo__age','userinfo__name') for i in obj: print(i['id'],i['title'],i['userinfo__name'],i['userinfo__age'])
1.4.4 元组取法
obj = models.UserType.objects.values_list('id','title','userinfo__name') print(obj[0],obj[1],obj[2])
1.5 排序 Order By
1.5.1 正序
user_list = models.UserInfo.objects.all().order_by('id') for i in user_list: print(i.id,i.name)
1.5.2 反序
user_list = models.UserInfo.objects.all().order_by('-id') for i in user_list: print(i.id,i.name)
1.6 分组 Group By
from django.db.models import Count,Max,Min,Sum user_list = models.UserInfo.objects.values('ut_id') print(user_list.query) query查看生成的sql语句 'SELECT "app01_userinfo"."ut_id" FROM "app01_userinfo"' user_list = models.UserInfo.objects.values('ut_id').annotate(alias=Count('id')) annotate聚合条件,如Count总数,Max最大数,Min最小数,Sum总和 print(user_list.query) 'SELECT "app01_userinfo"."ut_id", COUNT("app01_userinfo"."id") AS "alias" FROM "app01_userinfo" GROUP BY "app01_userinfo"."ut_id"' print(user_list)
1.7 二次过滤 Having
user_list = models.UserInfo.objects.values('ut_id').annotate(alias=Max('age')).filter(alias__gt=16) 最后的filter表示sql语句中的having,第二次过滤 print(user_list.query) 'SELECT "app01_userinfo"."ut_id", MAX("app01_userinfo"."age") AS "alias" FROM "app01_userinfo" GROUP BY "app01_userinfo"."ut_id" HAVING MAX("app01_userinfo"."age") > 16' print(user_list)
1.8 神奇的双下划线
models.UserInfo.objects.filter(id__lt=2) 小于 models.UserInfo.objects.filter(id__gt=1) 大于 models.UserInfo.objects.filter(id__lte=1) 小于等于 models.UserInfo.objects.filter(id__gte=1) 大于等于 models.UserInfo.objects.filter(id__in=[1,2,3]) 在...里面 models.UserInfo.objects.filter(id__range=[1,4]) 在一个范围内 models.UserInfo.objects.filter(name__contains='xxx') 模糊匹配,相当于sql中的like models.UserInfo.objects.filter(name__endswith='xxx') 以什么结尾 models.UserInfo.objects.filter(name__startswith='xxx') 以什么开头 models.UserInfo.objects.exclude(id=1) 不等于,exclude 排除
1.9 F 批量更新
from django.db.models import F,Q models.UserInfo.objects.all().update(age = F('age') + 1) 更新的的时候用F
1.10 Q 用于构造复杂的查询条件
q1 = Q() q1.connector = 'OR' q1.children.append(('id',1)) q1.children.append(('id',3)) q2 = Q() q2.connector = 'OR' q2.children.append(('ut_id',2)) q2.children.append(('ut_id',3)) con = Q() con.add(q1,'AND') con.add(q2,'AND' user_list = models.UserInfo.objects.filter(con) for n in user_list: print(n.name)
1.11 extra 进阶版sql查询
extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) 映射:指子查询的sql语句 select select_params 条件 原生表的sql的条件 where params 表 多个表联查,第一个表后接的表名 tables 排序 对结果正序或倒序排序 order_by 写法 models.UserInfo.objects.all().extra( select={'num':"select count(*) from app01_usertype WHERE id = %s"}, 字典形式的子查询语句,num相当于别名 select_params=[1,], 对应%s传值 tables=['app01_usertype'], 后面接的表名 where=['age > %s',], 原表的条件 params=[15,], 对应的%s传值 order_by=['-age'] 排序 )
1.12 原生sql
sql连接 from django.db import connection,connections # cursor = connection.cursor() # 通过django自动连接settings中设置的第一个数据库 cursor = connections['default'].cursor() # default表示settings中设置的第一个库,当然还可以选择别的库 cursor.execute('select * from app01_userinfo') # 原生sql语句,其余用法和pymysql一样 # row = cursor.fetchone() row = cursor.fetchall() for line in row: print(line)
2 其他小功能
http://www.cnblogs.com/wupeiqi/articles/6216618.html
3. 性能相关:
3.1 主动做连表
select_related('外键字段') 表之间进行join连表操作,一次性获取相关数据 user_info = models.UserInfo.objects.all().select_related('ut',) 如果多个foreignkey的字段就写多个,单次查询 for user in user_info: user_info是queryset对象,被循环后,user则是userinfo对象,可以直接用.的方式取值 print(user.name,user.age,user.ut.title)
3.2 不做连表,进行多次sql查询
prefetch_related('外键字段') user_info = models.UserInfo.objects.all().prefetch_related('ut',) 用prefetch_related则是做两次查询 for user in user_info: user_info是queryset对象,被循环后,user则是useringo对象,可以直接用.的方式取值 print(user.name,user.age,user.ut.title)
3.3 多对多:
自己手动创建第三张表Love,通过ForeinKey连接
class Love(models.Model): g = ForeignKey('Girl') b = ForeignKey('Boy') love_list = models.Love.objects.filter(b__name='张三') # 通过Love中的b字段去查询boy表中指定条件所对应的结果,love_list为queryset对象 for i in love_list: print(i.g.nick) love_list = models.Love.objects.filter(b__name='张三').values('g__nick') # love_list为字典类型 for i in love_list: print(i['g__nick']) love_list = models.Love.objects.filter(b__name='张三').select_related('g') # love_list为queryset对象 for i in love_list: print(i.g.nick)
4. Django自带第三张表的操作
ManyToMany 这个参数可是自动生成第三张表 class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField('Girl') 生成表的同时并关联到另一张表 class Girl(models.Model): nick = models.CharField(max_length=32)
4.1 添加数据到新生成表 add()
4.1.1 第一种方法,只添加一个
i.m.add(4)
4.1.2 第二种方法,添加多个
i.m.add(1,3)
4.1.3 第三种方法,列表形式添加
i.m.add(*[2,])
4.2 删除数据 remove()
4.2.1 第一种删除方式
i.m.remove(2)
4.2.2 第二种删除方式
i.m.remove(1,3)
4.2.3 第三种删除方式
i.m.remove(*[4,1,])
4.3 替换数据 set()
i.m.set([1,]) set里面传值只能是传可迭代对象
4.4 清空数据 clear()
i.m.clear() 清空所有,不论原来有多少数据
4.5 反向查询
obj = models.Girl.objects.filter(nick='王五') for i in obj: for n in i.boy_set.all(): print(n.name)