Django中通过一对一关联模型字段过滤查询集的方法
Django跨关联表过滤查询报错解决方案
预设模型定义
现有两个Django模型定义如下:
class A(models.Model): name = models.CharField(max_length=150) class B(models.Model): a = models.OneToOneField( to=A, on_delete=models.CASCADE, null=False ) location = models.CharField(max_length=100)
需求目标
需要查询B模型的QuerySet,过滤条件包含两部分:
- 关联A模型的
name字段匹配指定值 - B模型自身的
location字段匹配指定值
对应原生SQL逻辑为:
select * from B join A on B.a_id = A.pk where A.name="name" and B.location="location";
原需求给出的SQL中
B.a.pk为表述笔误,Django自动生成的外键列名为a_id,存储关联A模型的主键值
错误写法问题
当前使用的查询写法会直接触发报错:
query=B.objects.filter(a.name=name)
触发报错的核心原因有两点:
- Python语法层面不允许函数的关键字参数名包含
.符号,该写法本身就不符合Python语法规范 - Django ORM的过滤参数不支持用
.点号访问关联模型字段
正确实现方式
Django ORM使用双下划线__ 作为跨关联关系访问字段的语法标识,过滤关联模型字段时,按照关联字段名__目标字段名的格式传参即可,ORM会自动生成对应的JOIN查询逻辑,无需手动编写表关联语句。
符合需求的正确查询代码如下:
# 代码中name、location替换为实际业务传入的变量值即可 query = B.objects.filter(a__name=name, location=location)
如果需要校验ORM实际生成的SQL是否符合预期,可直接打印QuerySet的query属性查看:
print(query.query)
该写法生成的SQL会自动完成B表与A表的内连接,过滤逻辑和给出的原生SQL完全一致。
内容的提问来源于stack exchange,提问作者Khalil Al-abadlih
相关产品推荐
相关产品推荐

