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')
View Code

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('...')
View Code

 

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 排除
View Code

 

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'] 排序
)
View Code

 

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)
View Code

 

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)
View Code

 

 

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)	


posted on 2019-02-27 17:33  花豆豆  阅读(233)  评论(0编辑  收藏  举报