Django双下划线查询

在 Django 中,双下划线(__)查询是一种强大的语法,用于在 ORM(对象关系映射)中跨关联模型进行字段查询,或使用内置查询表达式(如过滤、聚合等)。以下是其核心用法和示例:

1. 跨关联模型查询

通过双下划线可以引用关联模型(ForeignKey、ManyToManyField、OneToOneField)的字段。

示例模型:

复制代码
class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

查询示例:

复制代码
# 查询作者名为"Alice"的所有书籍
books = Book.objects.filter(author__name="Alice")

# 查询所有写过标题包含"Python"的书籍的作者
authors = Author.objects.filter(book__title__icontains="Python")

2. 字段查找表达式

双下划线后可接多种查询表达式,如:
比较运算符

exact:精确匹配(默认)

gt、gte、lt、lte:大于、大于等于、小于、小于等于

in:包含在列表中

range:范围查询

示例:

复制代码
# 查询价格大于100的产品
products = Product.objects.filter(price__gt=100)

# 查询ID为1、3、5的用户
users = User.objects.filter(id__in=[1, 3, 5])

字符串处理

contains、icontains:包含(区分 / 不区分大小写)

startswith、istartswith:以... 开头

endswith、iendswith:以... 结尾

regex、iregex:正则表达式匹配

示例:

复制代码
# 查询邮箱以"@gmail.com"结尾的用户
users = User.objects.filter(email__endswith="@gmail.com")

日期和时间处理

year、month、day:提取日期部分

hour、minute、second:提取时间部分

date:日期比较

time:时间比较

示例:

复制代码
# 查询2023年创建的订单
orders = Order.objects.filter(created_at__year=2023)

# 查询昨天创建的所有对象
from datetime import date, timedelta
yesterday = date.today() - timedelta(days=1)
objects = MyModel.objects.filter(created_at__date=yesterday)

空值和布尔值

isnull:是否为空(True/False)

exact:布尔值匹配

示例:

复制代码
# 查询没有关联图片的文章
articles = Article.objects.filter(image__isnull=True)

# 查询已发布的文章
articles = Article.objects.filter(is_published__exact=True)

3. 多级跨关联查询

可以通过多个双下划线连接多层关联模型。

示例模型:

复制代码
class Country(models.Model):
    name = models.CharField(max_length=100)

class City(models.Model):
    name = models.CharField(max_length=100)
    country = models.ForeignKey(Country, on_delete=models.CASCADE)

class User(models.Model):
    name = models.CharField(max_length=100)
    city = models.ForeignKey(City, on_delete=models.CASCADE)

查询示例:

复制代码
# 查询来自中国北京的所有用户
users = User.objects.filter(city__name="Beijing", city__country__name="China")

4. 聚合查询与双下划线

在聚合函数(如Sum、Avg)中也可使用双下划线跨模型引用字段。

示例:

复制代码
from django.db.models import Sum
# 计算每个作者的总书籍销量
authors = Author.objects.annotate(total_sales=Sum("book__sales"))

注意事项

性能问题:多级跨关联可能导致 SQL 查询复杂度增加,建议结合select_related()或prefetch_related()优化。

反向关联:通过关联模型反向查询时,默认使用模型名小写加_set(如author.book_set.all()),但在双下划线查询中可直接使用模型名小写(如author__name)。

空值处理:使用跨关联查询时,若关联对象不存在,查询结果可能为空,需谨慎处理。

通过双下划线查询,Django ORM 可以简洁地表达复杂的数据库查询逻辑,避免编写原生 SQL。

相关推荐
Fireworkitte8 分钟前
Couchbase 详解
数据库
涛思数据(TDengine)8 分钟前
时序数据库厂商 TDengine 发布 AI 原生的工业数据管理平台 IDMP,“无问智推”改变数据消费范式
大数据·运维·数据库·人工智能·tdengine
想你依然心痛14 分钟前
Spark大数据分与实践笔记(第五章 HBase分布式数据库-04)
大数据·数据库·分布式
Circ.17 分钟前
使用es实现全文检索并且高亮显示
elasticsearch·django·全文检索
小王子102427 分钟前
Django模型迁移指南:从命令用法到最佳实践
数据库·mysql·django·迁移回滚
l_c-l-o-u-d_21 小时前
第十九周-文档数据库MongoDB、消息队列和微服务
数据库·redis·mongodb
数据狐(DataFox)1 小时前
大数据集分页优化:LIMIT OFFSET的替代方案
数据库·sql·oracle
bigcarp1 小时前
MySql插入中文生僻字/Emoji报错django.db.utils.DataError: (1366, “Incorrect string value
数据库·mysql·django
码界筑梦坊1 小时前
169-Django二手交易校园购物系统开发分享
后端·python·django·毕业设计·conda
正在走向自律2 小时前
企业微信API接口发消息实战:从0到1的技术突破之旅
java·数据库·企业微信·accesstoken·agentid·corpid·企业微信发消息