Django Models 查询操作
1.准备数据表:
from django.db import models class city(models.model): name=models.charfield(max_length=32) nid=models.autofield(primary_key=true) class author(models.model): name=models.charfield(max_length=32) nid=models.autofield(primary_key=true) city=models.foreignkey(to=city,on_delete=models.cascade) class book(models.model): nid=models.autofield(primary_key=true) title=models.charfield(max_length=32) author=models.manytomanyfield(to=author) #中间表,不用写on_delete class info(models.model): telephone=models.integerfield() nid=models.autofield(primary_key=true) author=models.onetoonefield(to=author,on_delete=models.cascade) #数据库中增加了字段author_id
2.插入数据:
models.city(name='losange').save() models.city(name='shanghai').save() models.book.objects.create(title='liao story') models.book.objects.create(title='spring') models.book.objects.create(title='old man and sea') models.book.objects.create(title='the sun rises') models.book.objects.create(title='cats') models.book.objects.create(title='lions') city=models.city.objects.first() models.author.objects.create(name='haimingwei',city=city) city=models.city.objects.all()[1] models.author.objects.create(name='xuewen',city=city)
3.查询操作
#1.跨表多对多查询
#模型关系 城市 <-- 作者 <-- 书
#查询haimingwei写的所有书籍
#基于对象-->反向查询(按表名_set) (返回queryset)
models.author.objects.get(name='haimingwei').book_set.values('title')
#基于queryset-->反向查询(按表名) (返回queryset)
models.author.objects.filter(name='haimingwei').values('book__title')
#基于queryset-->正向查询(按字段) (返回queryset)
models.book.objects.filter(author__name='haimingwei').values('title')
#查询spring这本书的作者
#基于对象-->正向查询(按字段) (返回queryset)
models.book.objects.get(title='spring').author.values('name')
#基于queryset-->反向查询(按表名) (返回queryset)
models.author.objects.filter(book__title='spring').values('name')
#基于queryset-->正向查询(按字段) (返回queryset)
models.book.objects.filter(title='spring').values('author__name')
#2.跨表一对多查询 #模型关系 城市 <-- 作者 <-- 书
#查询shanghai所有的作者
#基于对象 --> 反向查询(按表名_set) (返回queryset)
models.city.objects.get(name='shanghai').author_set.values('name')
#基于queryset --> 反向查询(按表名)
models.city.objects.filter(name='shanghai').values('author__name')
#基于queryset --> 正向查询(按字段)(返回queryset)
models.author.objects.filter(city__name='shanghai').values('name')
#查询海明威所在的城市
#基于对象 --> 正向查询 (按字段) (返回object)
models.author.objects.get(name='haimingwei').city.name
#基于queryset --> 反向查询(按表名)
models.city.objects.filter(author__name='haimingwei').values('name')
##基于queryset --> 正向查询(按字段)
models.author.objects.filter(name='haimingwei').values('city__name')
#3.跨表一对一查询
#模型关系 作者 <-- 作者信息
#查询手机号为123的作者
#基于对象 --> 正向查询 (按字段) (返回object)
models.info.objects.get(telephone=123).author.name
#基于queryset --> 正向查询(按字段)
models.info.objects.filter(telephone=123).values('author__name')
#基于queryset --> 反向查询(按表名)
models.author.objects.filter(info__telephone=123).values('name')
#查询haimingwei的手机号
#基于对象 --> 反向查询 (按表名) (返回object!!!)
models.author.objects.get(name='haimingwei').info.telephone
#基于queryset --> 正向查询(按字段)
models.info.objects.filter(author__name='haimingwei').values('telephone')
#基于queryset --> 反向查询(按表名)
models.author.objects.filter(name='haimingwei').values('info__telephone')
#查询写old man and sea这本书作者所在的城市 -->跨三张表查询!
#models.city.objects.filter(author__book__title='old man and sea').values('name')
#models.book.objects.filter(title='old man and sea').values('author__city__name')
#models.author.objects.filter(book__title='old man and sea').values('city__name')
from django.db.models import max,avg,f,q,min,count,sum
#聚合查询 --> 返回一个字典
models.info.objects.aggregate(total=sum('telephone'))
#分组查询 -->不管是单表还是跨表一律都是基于queryset的查询
#模型关系 城市 <-- 作者 <-- 书
#查询每个作者写的书籍总数 -->作者作为基表
models.author.objects.values('name').annotate(each_total=count('book__title')).values('name','each_total')
#查询每个作者写的书籍总数 -->书作为基表
models.book.objects.values('author__name').annotate(each_total=count('title')).values('each_total')
#查询每本书的作者个数
models.book.objects.values('title').annotate(total=count('author__nid'))
models.author.objects.values('book__title').annotate(total=count('nid'))
#查询不止一个作者的书籍
models.book.objects.values('nid').annotate(c=count('author__nid')).filter(c__gt=1).values('title','c')
#f查询
#比较不同字段值
models.info.objects.filter(telephone__gt=f('nid'))
models.info.objects.filter(telephone__gt=f('nid')*2)
#修改字段值
models.info.objects.update(telephone=f('telephone')*2).values('telephone')
#q查询
#查询xuewen或海明威所写的书
models.book.objects.filter(q(author__name='haimingwei')|q(author__name='xuewen')).values('title')
总结:
- 查询返回多个对象时,返回值为queryset;
- 基于对象反向查询时,表名_set!
- 确定返回一个对象时,返回值为object!