django 框架 SQL 语句 查询篇

本文详细介绍了在Django框架中进行SQL查询的操作,包括多表操作、一对一、一对多和多对多的关系处理,以及如何进行增加、删除和查询。重点讲解了基于双下划线的查询方式,同时涵盖了聚合、分组以及使用F和Q表达式的高级查询技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明我们在设计SQL语句的时候,将表仔细创建,这里很重要,后期就最好不要动了

设计表,将各个表之间的对应关系梳理清楚,这是对表查询的重要的步骤

 

 

多表操作

一对一:

增删改查
​	model.Author.objects.create(name='二哥',age=59,ad_id=1)
删除
​	model.Author.objects.filter(id=1).delete()
改
​	model.Author.objects.filter(id=1).update(name='2ge2')
查
​	正向:
​		model.Author.objects.filter(id=1)[0].ad.telephone
​	反向
​		ad_obj =	model.AuthorDetail.objects.filter(telephone=111)[0]
​		ad_obj.author.id

一对多:

增加:
​		model.Book.objects.create(title='xx',price=12,publish_id=1)
​		model.Book.objects.create(title='xx',price=12,publish=publish的model对象)
​	删除
​		model.Book.objects.filter(id=3)[0].delete()
​		model.Book.objects.filter(id=3).delete()
​	修改:
​		model.Book.objects.filter(id=3).update(title='xxx',publish_id=2)
​	查询
​		反向查询:红浪漫出版社出版过哪些书籍(只要名称)
​			pub_obj = model.Publish.objects.filter(name='红浪漫出版社').first()
​			pub_obj. book_set.all().value()    .value_list() 
​			 .filter(xxx=xxx)  
    author_obj = models.Author.objects.get(name='二哥')
    print(author_obj.book_set.all().values('title').filter(title='linux')) #	<QuerySet [{'title': 'linux'}, {'title': 'linux'}]>
​		正向查询:
​			book_obj = models.Book.objects.filter(title='jinpinmei').first()
​            book_obj .publish.name

多对多的

增加

    book_obj = models.Book.objects.create(title='水浒',price=11,publish_id=1)
    authorerge = models.Author.objects.get(name='二哥')
    authorsange = models.Author.objects.get(name='三哥')
    book_obj.authors.add(*[authorerge,authorsange])
    book_obj.authors.add(*[authorerge.id,authorsange.id])

删除

    book_obj.authors.remove(authorerge)
    book_obj.authors.remove(1)
    book_obj.authors.remove(1,2,3)
    book_obj.authors.remove(*[1,2,3])
    book_obj.authors.clear()
    book_obj.authors.set(['1','2',])

查询:

正向查询:

   book_obj = models.Book.objects.get(title='水浒')
   book_obj.authors.all().values('name'),.values_list('name')
   book_obj.authors.filter()
   

反向查询

	authorsange = models.Author.objects.get(name='三哥')
	authorsange.book_set.all().values('title')

基于双下划线的查询

一对一
	查一下雄哥的手机号
models.Author.objects.filter(name='雄哥').values('ad__telephone')
models.AuthorDetail.objects.filter(author__name='雄哥').values('telephone')

一对多
	红浪漫出版了哪些书
models.Publish.objects.filter(name='红浪漫出版社').values('book__title')
models.Book.objects.fitler(publishs__name='红浪漫出版社').values('title')

多对多
	python这本书是哪些作者写的
models.Book.objects.filter(title='python').values('authors__name')
models.Author.objects.filter(book__title='python').values('name')

聚合

查询一下所有书的平均价格
from django.db.models import Avg,Max,Min,Count,Sum
models.Book.objects.all().aggregate(a=Avg('price')) #结果是个字典

分组

查询作者出版过的书的平均价格
models.Author.objects.values('name').annotate(a=Avg('book__price'))

#这里annotate是分组,以name分组
#annotate只能以前面的values作为分组条件,如果没有则以第一个表的ID分组

models.Book.objects.values('authors__name').annotate(a=Avg('price'))

F

   在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?我们在book表里面加上两个字段:评论数:commentNum,收藏数:KeepNum

  Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

我先查看点赞数小于评论数的所有书籍
from django.db.models import F
model.Book.objects.filter(zan__lt=F('comment'))
统一给价格加100块
model.Book.objects.all().update(price=F('price')+100)

Q

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。

Q 对象可以使用&(与) 、|(或)、~(非) 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。

查询2019年的点赞数小于100的,或者评论小于100的书籍名称和价格
models.Book.objects.filter(Q(zan__lt=100)|Q(comment__lt=100),date__year=2019).values('title','price')
#1 查询每个作者的姓名以及出版的书的最高价格
ret = models.Author.objects.annotate(m=Max('book__price')).values('name','m')
#这里annotate是分组,以Author表中的ID分组,其中values省略了
#annotate只能以前面的values作为分组条件
#ret 获取到的值是annotate里面的m值和id的值,如果想要更多则在后面添加values写自己需要的值

ret = models.Book.objects.values('authors__name').annotate(m=Max('price'))
print(ret)

#2 查询作者id大于2作者的姓名以及出版的书的最高价格
models.Author.objects.filter(id__gt=2).annotate(m=Max('book__price')).values('name','m')

#3 查询作者id大于2或者作者年龄大于等于20岁的,女作者的姓名以及出版的书的最高价格
models.Author.objects.filter(Q(sex='女')&Q(Q(id__gt=2)|Q(age__gte=20))).values('name').annotate(m=Max('book__price'))
#4 查询每个作者出版的书的最高价格 的平均值
models.Author.objects.values('id').annotate(a=Max('book__price')).aggregate(m=Avg('a'))
#5 每个作者出版的所有书的最高价格的那本书的名称
models.Author.objects.values('name').annotate(a=Max('book__price')).values('book__title')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值