1. 查询操作
1.1 filter()
用法:
- 用于过滤查询结果,返回符合条件的记录。
- 支持链式调用。
示例:
queryset = MyModel.objects.filter(field=value)
SQL 查询示例:
SELECT * FROM MyModel WHERE field = value;
性能特点:
- 根据过滤条件生成 SQL 查询。
- 支持复杂查询条件,性能取决于查询条件和索引。
1.2 exclude()
用法:
- 用于排除符合条件的记录。
- 结果集为所有不符合条件的记录。
示例:
queryset = MyModel.objects.exclude(field=value)
SQL 查询示例:
SELECT * FROM MyModel WHERE field != value;
性能特点:
- 类似于
filter()
,但条件是排除的。 - 适用于排除某些不需要的记录。
1.3 get()
用法:
- 用于获取唯一的记录。如果查询条件匹配到多个记录,会引发
MultipleObjectsReturned
异常。
示例:
obj = MyModel.objects.get(id=1)
SQL 查询示例:
SELECT * FROM MyModel WHERE id = 1 LIMIT 1;
性能特点:
- 执行带有
LIMIT 1
的查询。 - 适用于查找唯一记录。
1.4 aggregate()
用法:
- 用于对查询结果进行聚合操作,如计数、求和、平均值等。
示例:
from django.db.models import Count, Sum
result = MyModel.objects.aggregate(total=Count('field'))
SQL 查询示例:
SELECT COUNT(field) AS total FROM MyModel;
性能特点:
- 使用聚合函数进行计算,性能依赖于数据量和聚合函数。 只返回聚合结果,不包括具体的记录数据。
1.5 annotate()
用法:
- 用于给每个记录添加计算字段或聚合结果。
示例:
from django.db.models import Count
queryset = MyModel.objects.annotate(num_related=Count('related_model'))
SQL 查询示例:
SELECT MyModel.*, COUNT(RelatedModel.id) AS num_related
FROM MyModel
LEFT JOIN RelatedModel ON MyModel.id = RelatedModel.parent_model_id
GROUP BY MyModel.id;
性能特点:
- 添加计算字段,使用
LEFT JOIN
和聚合操作。 执行带有GROUP BY
的查询,计算每个记录的聚合数据。
1.6 values()
用法:
- 返回一个包含字典的 QuerySet,每个字典代表一行数据。
示例:
queryset = MyModel.objects.values('field1', 'field2')
SQL 查询示例:
SELECT field1, field2 FROM MyModel;
性能特点:
- 只返回指定字段,减少数据传输量。
1.7 values_list()
用法:
- 返回一个包含元组的 QuerySet,每个元组代表一行数据。
示例:
queryset = MyModel.objects.values_list('field1', 'field2')
SQL 查询示例:
SELECT field1, field2 FROM MyModel;
性能特点:
- 返回元组数据,适合处理不需要字段名称的结果。
2. 更新操作
2.1 update()
用法:
- 用于批量更新符合条件的记录。
示例:
MyModel.objects.filter(condition).update(field=value)
SQL 查询示例:
UPDATE MyModel SET field = value WHERE condition;
性能特点:
- 高效的批量更新操作,不会触发
save()
方法。
3. 删除操作
3.1 delete()
用法:
- 用于删除符合条件的记录。删除操作会触发模型的
delete()
方法。
示例:
MyModel.objects.filter(condition).delete()
SQL 查询示例:
DELETE FROM MyModel WHERE condition;
性能特点:
- 删除操作会在数据库中实际删除记录,可能触发级联删除和信号处理。
4. 关联查询
4.1 select_related()
用法:
- 用于一对一和外键关系的优化查询,通过
INNER JOIN
一次性加载所有关联数据。
示例:
queryset = MyModel.objects.select_related('related_model')
SQL 查询示例:
SELECT MyModel.*, RelatedModel.*
FROM MyModel
INNER JOIN RelatedModel ON MyModel.related_model_id = RelatedModel.id;
性能特点:
- 高效减少数据库查询次数,但可能丢失主表记录(因
INNER JOIN
)。
4.2 prefetch_related()
用法:
- 用于一对多和多对多关系的优化查询,通过多个查询在 Python 层面合并结果。
示例:
queryset = MyModel.objects.prefetch_related('related_model')
SQL 查询示例:
-- 第一个查询
SELECT * FROM MyModel;
-- 第二个查询
SELECT * FROM RelatedModel WHERE related_model_id IN (1, 2, 3, ...);
性能特点:
- 不丢失主表记录,适用于复杂关系,但可能增加查询时间和内存使用。
4.3 .
查询(点操作符)
用法:
- 用于通过点操作符访问外键字段。
示例:
queryset = MyModel.objects.filter(related_model__field=value)
SQL 查询示例:
SELECT * FROM MyModel
INNER JOIN RelatedModel ON MyModel.related_model_id = RelatedModel.id
WHERE RelatedModel.field = value;
性能特点:
- 主表记录仅在关联表中有匹配记录时才会返回,可能导致额外查询(N+1 问题)。
1:首先执行一个查询,从主表中获取数据(比如,获取 N 个对象)。
N:对于每个从主表返回的记录,再执行额外的查询去获取关联数据(比如,获取每个对象的外键关系的详细信息)。
books = Book.objects.all()
for book in books:
print(book.author.name)
解决 N+1 问题的常见方法是使用 select_related()(一对一或外键关系)和 prefetch_related()(多对多或反向外键关系)来减少数据库查询次数。
4.4 __
查询(双下划线语法)
用法:
- 用于跨表字段查询,支持条件过滤和字段选择。
示例:
queryset = MyModel.objects.filter(related_model__field=value).values('field')
SQL 查询示例:
SELECT MyModel.field, RelatedModel.field
FROM MyModel
INNER JOIN RelatedModel ON MyModel.related_model_id = RelatedModel.id
WHERE RelatedModel.field = value;
性能特点:
- 支持复杂查询,但可能丢失主表记录(因
INNER JOIN
),查询复杂性高。
总结与比较
- 查询操作:
filter()
和exclude()
支持灵活的条件查询,get()
用于获取唯一记录,aggregate()
和annotate()
用于聚合和计算,values()
和values_list()
用于简化数据获取。 - 更新操作:
update()
高效批量更新记录。 - 删除操作:
delete()
删除记录并触发相关信号和级联删除。 - 关联查询:
select_related
: 适用于一对一和外键关系,通过INNER JOIN
加载数据,丢失主表记录的风险。prefetch_related
: 适用于一对多和多对多关系,通过多个查询加载数据,确保主表记录。.
查询: 通过点操作符访问外键字段,可能导致额外查询(N+1 问题)。__
查询: 支持复杂的跨表查询,使用INNER JOIN
,主表记录可能丢失。