相关知识盘点:查看orm内部sql语句的方法 1.看是否是queryset 对象,是的话,可直接.query查看SQL语句; 2.在django配置文件中,配置相关参数,orm查询时自动打印sql语句; LOGGING = { ‘version‘: 1, ‘disable_existing_loggers‘: False, ‘handlers‘: { ‘console‘:{ ‘level‘:‘DEBUG‘, ‘class‘:‘logging.StreamHandler‘, }, }, ‘loggers‘: { ‘django.db.backends‘: { ‘handlers‘: [‘console‘], ‘propagate‘: True, ‘level‘:‘DEBUG‘, }, } } 案例相关: from django.db import models class Book(models.Model): title = models.CharField(max_length=255) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) # 库存数 kucun = models.IntegerField(null=True) # 卖出数 maichu = models.IntegerField(null=True) publish = models.ForeignKey(to=‘Publish‘) # 默认是跟publish的主键字段做的一对多外键关联 authors = models.ManyToManyField(to=‘Author‘) # 虚拟字段 1.自动创建第三张表 2.帮助orm跨表查询 class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) # email = models.EmailField() # 就是varchar(254) class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to=‘AuthorDetail‘) class AuthorDetail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=64) 1.查询的方法: 1.all(): 查询所有结果 2.filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 3.get(**kwargs): 返回数据对象,结果只有一个,没匹配到报错 4.exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 eg: print(models.Book.objects.exclude(pk=1)) #只要pk不是1的数据全部查询出来 5.order_by(*field): 对查询结果排序;默认是升序,加-就是降序 eg: print(models.Book.objects.order_by(‘price‘)) # 默认是升序 print(models.Book.objects.order_by(‘-price‘)) # 加负号就是降序 6.reverse(): 对查询结果反向排序 eg: print(models.Book.objects.order_by(‘price‘).reverse()) 注:前面要先有排序才能反向 7.count(): 返回数据库中匹配查询(QuerySet) eg: print(models.Book.objects.count()) #对查询出来的结果进行一个计数 8.first(): 返回第一条记录 9.last(): 返回最后一条记录 10.exists():存在返回True,否则返回False eg: print(models.Book.objects.filter(pk=1000).exists()) 11.values(*field): 返回一个ValueQuerySet对象,运行后得到的并不是一系列 eg: print(models.Book.objects.values(‘title‘,‘price‘)) # 得到的结果是列表套字典 12.values_list(*field): 它与values()类似 eg: print(models.Book.objects.values_list(‘title‘,‘price‘)) # 得到的结果是列表套元组 13.distinct(): 从返回结果中剔除重复纪录 eg: print(models.Book.objects.values(‘title‘,‘price‘,‘create_time‘).distinct()) 注:去重的前提是 一定要有完全重复的数据 才能去重 2.双下滑查询: 1.__gt: 大于 eg:查询价格大于200的书籍 res = models.Book.objects.filter(price__gt=200) 2.__lt: 小于 eg:查询价格小于200的书籍 res = models.Book.objects.filter(price__lt=200) 3.__gte:大于等于 eg:查询价格大于等于200.22的书籍 res = models.Book.objects.filter(price__gte=200.22) 4.__lte:小于等于 eg:查询价格小于等于200.22的书籍 res = models.Book.objects.filter(price__lte=200.22) 5.__in:或者 eg:查询价格要么是200,要么是300,要么是666.66 res = models.Book.objects.filter(price__in=[200,300,666.66]) 6.__range:区间 左右都包括 eg:查询价格在200到800之间的 res = models.Book.objects.filter(price__range=(200,800)) 7.__contains:模糊匹配 eg:查询书籍名字中包含p的 res = models.Book.objects.filter(title__contains=‘p‘) # 仅仅只能拿小写p res = models.Book.objects.filter(title__icontains=‘p‘) # 忽略大小写 8.__startswith:以...开头 eg:查询书籍是以三开头的 res = models.Book.objects.filter(title__startswith=‘三‘) 9.__endswith:以...结尾 eg:查询书籍是以三结尾的 res = models.Book.objects.filter(title__endswith=‘三‘) 10.__year:查询年相关的 eg:查询出版日期是2017的年(******) res = models.Book.objects.filter(create_time__year=‘2017‘) 3.多表查询: 一对多的字段的增删改查: 增: publish_id传数字: models.Book.objects.create(title=‘三国演义‘,price=189.99,publish_id=1) publish直接传出版社对象: publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.create(title=‘红楼梦‘,price=999.99,publish=publish_obj) 改: 传数字的: models.Book.objects.filter(pk=1).update(publish_id=3) 传对象的: publish_obj = models.Publish.objects.filter(pk=2).first() models.Book.objects.filter(pk=1).update(publish=publish_obj) 删: models.Publish.objects.filter(pk=2).delete() # 默认都是级联更新 级联删除 多对多字段的增删改查: 增(add):既可以传数字也可以传对象并且支持一次性传多个,逗号隔开即可 1.要给主键为1的书籍添加两个作者 传数字: book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.add(1) book_obj.authors.add(2,3) 传对象: author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() author_obj2 = models.Author.objects.filter(pk=3).first() book_obj.authors.add(author_obj) book_obj.authors.add(author_obj1,author_obj2) 改(set): 1.将主键为1的书籍对象 作者修改为2,3 传数字: book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.set([2,]) book_obj.authors.set([2,3]) 传对象: author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() author_obj2 = models.Author.objects.filter(pk=3).first() book_obj.authors.set([author_obj,]) book_obj.authors.set([author_obj, author_obj1, author_obj2]) 注:1.set中要传可迭代对象,可迭代对象中 可以是多个数字组合也可以是多个对象组合; 2.数字与对象不要混着用!!! 删(remove|clear):remove支持传数字,对象,并且可以传多个; clear不需要传任何参数 传数字: book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.remove(3) book_obj.authors.remove(1,2) 传对象: author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() author_obj2 = models.Author.objects.filter(pk=3).first() book_obj.authors.remove(author_obj) book_obj.authors.remove(author_obj1,author_obj2) 什么都不传:将xx跟xx的关系全部清空 book_obj = models.Book.objects.filter(pk=1).first() book_obj.authors.clear() # 清空当前书籍与作者的所有关系 注: 对象点击多对多虚拟字段 会直接跨到多对多的第三张表 4.跨表查询: 正向与反向概念: 1.一对一 正向:author---关联字段在author表里--->authordetail 按字段 反向:authordetail---关联字段在author表里--->author 按表名小写 2.一对多 正向:book---关联字段在book表里--->publish 按字段 反向:publish---关联字段在book表里--->book 按表名小写_set.all() 因为一个出版社对应着多个图书 3.多对多 正向:book---关联字段在book表里--->author 按字段 反向:author---关联字段在book表里--->book 按表名小写_set.all() 因为一个作者对应着多个图书 小结:(*****) 正向查询按外键字段查,反向查询按表名小写 子查询:将一张表的查询结果当做另外一个查询语句的条件 1.查询书籍id是1 的出版社名称 book_obj = models.Book.objects.filter(pk=1).first() print(book_obj.publish.name) 2.查询书籍id是2 的作者姓名 book_obj = models.Book.objects.filter(pk=2).first() print(book_obj.authors) # app01.Author.None print(book_obj.authors.all()) res = book_obj.authors.all() for r in res: print(r.name) 3.查询作者是jason的家庭住址 author_obj = models.Author.objects.filter(name=‘jason‘).first() print(author_obj.author_detail.addr) 4.查询出版社是东方出版社出版的书籍 publish_obj = models.Publish.objects.filter(name=‘东方出版社‘).first() # print(publish_obj.book_set) # app01.Book.None print(publish_obj.book_set.all()) 5.查询作者是jason的写过的所有的书籍 author_obj = models.Author.objects.filter(name=‘jason‘).first() print(author_obj.book_set) # app01.Book.None print(author_obj.book_set.all()) 6.查询电话号码是130的作者姓名 author_detail_obj = models.AuthorDetail.objects.filter(phone=130).first() print(author_detail_obj.author.name) print(author_detail_obj.author.age) 7.查询书籍id为1 的作者的电话号码 book_obj = models.Book.objects.filter(pk=1).first() author_list = book_obj.authors.all() for author_obj in author_list: print(author_obj.author_detail.phone) 小结: 当反向查询的结果有多个时,要在后面加上_set; 连表操作(基于__): 1.查询jason作者的手机号 正向: res = models.Author.objects.filter(name=‘jason‘).values(‘author_detail__phone‘,‘author_detail__addr‘) print(res) 反向: res1 = models.AuthorDetail.objects.filter(author__name=‘jason‘).values(‘phone‘) print(res1) 2.查询jason这个作者的年龄和手机号 正向 res = models.Author.objects.filter(name=‘jason‘).values(‘age‘,‘author_detail__phone‘) print(res) 反向 res1 = models.AuthorDetail.objects.filter(author__name=‘jason‘).values(‘phone‘,‘author__age‘) print(res1) 3.查询手机号是130的作者年龄 正向 res = models.AuthorDetail.objects.filter(phone=130).values(‘author__age‘) print(res) 反向: res1 = models.Author.objects.filter(author_detail__phone=130).values(‘age‘) print(res1) 4.查询书籍id是1 的作者的电话号码 res = models.Book.objects.filter(pk=1).values(‘authors__author_detail__phone‘) print(res) 5.查询出版社为北方出版社的所有图书的名字和价格 res = models.Publish.objects.filter(name=‘北方出版社‘).values(‘book__title‘,‘book__price‘) print(res) 6.查询北方出版社出版的价格大于19的书 res = models.Book.objects.filter(price__gt=19,publish__name=‘北方出版社‘).values(‘title‘,‘publish__name‘) print(res) 注:只要表里面有外键字段,你就可以无限制跨多张表 eg:外键字段1__外键字段2...__外键字段__普通字段n 聚合查询(aggregate):最大,最小,个数,平均,总和 先导入 from django.db.models import Max,Min,Count,Avg,Sum... res = models.Book.objects.aggregate(Sum(‘price‘)) res1 = models.Book.objects.aggregate(Avg(‘price‘)) res2 = models.Book.objects.aggregate(Count(‘price‘)) res3 = models.Book.objects.aggregate(Max(‘price‘)) res4 = models.Book.objects.aggregate(Min(‘price‘)) res5 = models.Book.objects.aggregate(Max(‘price‘),Min(‘price‘),Count(‘pk‘),Avg(‘price‘),Sum(‘price‘)) 注: aggregate(后面可跟多个函数) 分组查询(annotate):models.那个表名就以那个分组 from django.db.models import Max, Min, Count, Avg, Sum 1.统计每一本书的作者个数 res = models.Book.objects.annotate(author_num = Count(‘authors‘)).values(‘author_num‘,‘title‘) print(res) 2.统计出每个出版社卖的最便宜的书的价格 res = models.Publish.objects.annotate(mmp = Min(‘book__price‘)).values(‘name‘,‘mmp‘) print(res) 3.统计不止一个作者的图书 res = models.Book.objects.annotate(author_num=Count(‘authors‘)).filter(author_num__gt=1) print(res) 4.查询各个作者出的书的总价格 res = models.Author.objects.annotate(sp=Sum(‘book__price‘)).values(‘name‘,‘sp‘) print(res) F查询:本质就是从数据库中获取某个字段的值 from django.db.models import F 1.查询卖出数量 res = models.Book.objects.filter(kucun__gt=F(‘maichu‘)) print(res) 2.将书籍库存数全部增加1000 models.Book.objects.update(kucun=F(‘kucun‘)+1000) 3.把所有书名后面加上‘新款‘ 要先导入: from django.db.models.functions import Concat from django.db.models import Value ret3 = models.Book.objects.update(title=Concat(F(‘title‘), Value(‘新款‘))) models.Book.objects.update(title = F(‘title‘)+‘新款‘) # 不能这么写 Q查询:默认and,可人为改为 or , not from django.db.models import Q 1.查询书籍名称是三国演义或者价格是444.44 and: res = models.Book.objects.filter(title=‘三国演义‘,price=444.44) # filter只支持and关系 res1 = models.Book.objects.filter(Q(title=‘三国演义‘),Q(price=444)) # 如果用逗号 那么还是and关系 or: res2 = models.Book.objects.filter(Q(title=‘三国演义‘)|Q(price=444)) not: res3 = models.Book.objects.filter(~Q(title=‘三国演义‘)|Q(price=444)) Q高级用法(了解): q = Q() q.connector = ‘or‘ # 修改查询条件的关系 默认是and q.children.append((‘title__contains‘,‘三国演义‘)) # 往列表中添加筛选条件 q.children.append((‘price__gt‘,444)) # 往列表中添加筛选条件 res = models.Book.objects.filter(q) # filter支持你直接传q对象 但是默认还是and关系 print(res)
原文:https://www.cnblogs.com/wyf20190411-/p/11552247.html