Django的高级查询

1. Q 对象:复杂查询条件

Q 对象允许你构建更复杂的查询条件,并进行逻辑运算(例如 ANDORNOT)。

from django.db.models import Q

# 查找作者为 "John Smith" 或价格小于 20 的书籍
books = Book.objects.filter(Q(author="John Smith") | Q(price__lt=20))

# 查找作者为 "John Smith" 且价格大于 20 的书籍
books = Book.objects.filter(Q(author="John Smith") & Q(price__gt=20))

# 查找不属于作者 "John Smith" 的书籍
books = Book.objects.filter(~Q(author="John Smith"))

2. F 对象:字段间比较

F 对象用于在数据库中进行字段间的比较,可以引用模型中的字段值并在查询中使用它们。

from django.db.models import F

# 查找价格大于成本的书籍
books = Book.objects.filter(price__gt=F('cost'))

详情可以查看Django查询表达式文章。

3. annotate():聚合和计算

annotate() 用于对查询集中的每一条记录进行聚合计算,例如计算每个作者的书籍数量或每个分类的书籍总价格。

from django.db.models import Count

# 为每位作者统计书籍数量
authors = Author.objects.annotate(num_books=Count('books'))

# 查看每位作者的书籍数量
for author in authors:
    print(f"{author.name} has written {author.num_books} books")





from django.db.models import Avg

# 为每位作者计算书籍的平均价格
authors = Author.objects.annotate(avg_price=Avg('books__price'))

# 查看每位作者书籍的平均价格
for author in authors:
    print(f"{author.name} has an average book price of {author.avg_price}")



from django.db.models import Sum

# 为每本书的作者计算所有书籍的总价
authors = Author.objects.annotate(total_books_price=Sum('books__price'))


# 查看每本书以及该书作者所有书籍的总价
for book in authors :
    print(f"The book  by {author.name} has a total price of all books by this author: {book.total_author_books_price}")

4. aggregate():全局聚合

aggregate() 用于对整个查询集进行聚合计算,返回一个字典,包含所有聚合结果。常见的聚合操作有 SumCountAvgMaxMin 等。

from django.db.models import Sum

# 计算所有书籍的总价格
total_price = Book.objects.aggregate(Sum('price'))

结果:{'price__sum': 1200.50}


from django.db.models import Count, Avg

# 计算书籍的数量和平均价格
summary = Book.objects.aggregate(num_books=Count('id'), avg_price=Avg('price'))
{'num_books': 100, 'avg_price': 25.50}

5. values() 和 values_list():提取特定字段

values()values_list() 用于从查询集中提取特定字段的数据。

#获取所有书籍的标题和作者
books = Book.objects.values('title', 'author')

结果:[
    {'title': 'Django for Beginners', 'author': 'John'},
    {'title': 'Python Crash Course', 'author': 'Eric'},
    ...
]



#获取所有书籍的标题和价格(返回元组)
books = Book.objects.values_list('title', 'price')

结果:[
    ('Django for Beginners', 'John'),
    ('Python Crash Course', 'Eric'),
    ...
]
如果values_list('title',flat=True)只有一个参数,且flat为true,则返回是一个列表

6. distinct():去重

distinct() 用于去除查询结果中的重复记录。

authors = Book.objects.values('author').distinct()
#这将返回所有不重复的作者列表。

7. Chaining Queries(链式查询)

Django ORM 支持链式查询,你可以将多个查询方法连在一起,执行更加复杂的查询。

Django 的查询集方法(如 filter()exclude()order_by() 等)会返回一个新的查询集,并不会修改原查询集。因此,可以连续调用这些方法,每次调用会进一步筛选或操作查询结果,形成链式查询。

books = Book.objects.filter(price__gt=20).order_by('-publication_date').exclude(author="John Smith")

# 获取所有价格大于 20 且分类为 "Science" 的书籍
books = Book.objects.filter(price__gt=20).filter(category='Science')

# 查找价格大于 20 且不属于 "Science" 类别的书籍
books = Book.objects.filter(price__gt=20).exclude(category='Science')

# 获取所有书籍的标题(价格大于 30 的),按标题字母顺序排序,并返回平铺列表
titles = Book.objects.filter(price__gt=30).order_by('title').values_list('title', flat=True)


# 获取价格大于 20 的书籍以及它们的作者信息,优化一对多查询
books = Book.objects.select_related('author').filter(price__gt=20)

select_related详情可以查看其他文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值