You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Django ORM按双外键条件关联model_B与model_C?

Django ORM实现多条件关联model_B与model_C

我希望以两个条件关联model_B和model_C:model_B的data_a与model_C的data_a匹配,且model_B的human与model_C的author匹配,请问如何通过Django ORM实现该操作?

模型代码

class user(models.Model):
    data_1 = models.CharField(max_length=60)
    data_2 = models.SmallIntegerField()
    data_3 = models.IntegerField(blank=True, null=True)

class model_A(models.Model):
    data_1 = models.CharField(max_length=60)
    data_2 = models.SmallIntegerField()
    data_3 = models.IntegerField(blank=True, null=True)

class model_B(models.Model):
    data_a = models.ForeignKey(model_A)
    human = models.ForeignKey(user)
    data_2 = models.IntegerField()

class model_C(models.Model):
    data_a = models.ForeignKey(model_A)
    author = models.ForeignKey(user)
    data_1 = models.CharField(max_length=5)
    data_2 = models.IntegerField()

场景1:筛选存在对应model_C的model_B记录

如果只需要找出满足双条件的model_B,用Exists子查询效率最优:

from django.db.models import Exists, OuterRef

valid_model_b = model_B.objects.filter(
    Exists(
        model_C.objects.filter(
            data_a=OuterRef('data_a'),
            author=OuterRef('human')
        )
    )
)

场景2:获取model_B对应的model_C字段值

如果需要把匹配的model_C字段直接映射到model_B的查询结果中,用Subquery实现:

from django.db.models import Subquery, OuterRef

# 定义匹配条件的子查询
matched_c = model_C.objects.filter(
    data_a=OuterRef('data_a'),
    author=OuterRef('human')
).values('data_1', 'data_2')[:1]

# 给model_B添加对应的model_C字段
model_b_with_c = model_B.objects.annotate(
    c_data1=Subquery(matched_c.values('data_1')),
    c_data2=Subquery(matched_c.values('data_2'))
)

# 示例:遍历获取数据
for item in model_b_with_c:
    print(f"model_B data_2: {item.data_2}, model_C data_1: {item.c_data1}")

场景3:关联查询两个模型的完整数据

如果需要同时获取model_B和对应model_C的完整数据,通过反向关联+条件过滤实现:

from django.db.models import F

# 关联查询满足条件的数据集
joined_data = model_B.objects.filter(
    data_a__model_c__author=F('human'),
    data_a__model_c__data_a=F('data_a')
).select_related('data_a', 'human').prefetch_related('data_a__model_c')

# 示例:访问关联的model_C数据
for b in joined_data:
    # 过滤出当前model_B对应的匹配model_C
    matched_c_list = [c for c in b.data_a.model_c_set.all() if c.author == b.human]
    for c in matched_c_list:
        print(f"model_B ID: {b.id}, model_C ID: {c.id}")

说明

  • 以上方法均使用Django ORM原生能力,无需手写SQL,保证代码可移植性。
  • 若模型设置了related_name,需将代码中默认反向关联名(如model_c_set)替换为自定义名称。

内容的提问来源于stack exchange,提问作者KIM Bucket

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:48:20