Django左加入?

2024-04-18 15:38:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我有模特,差不多是这样的:

class ModelA(models.Model):
    field = models.CharField(..)

class ModelB(models.Model):
    name = models.CharField(.., unique=True)
    modela = models.ForeignKey(ModelA, blank=True, related_name='modelbs')

    class Meta:
        unique_together = ('name','modela')

我想做一个这样的查询:“获取所有model a的where字段名等于X,并且ModelB模型的名称为X或根本没有模型名”

到目前为止我有这个:

ModelA.objects.exclude(field=condition).filter(modelsbs__name=condition)

这将得到所有至少有一个modelB的ModelA(实际上它总是一个),但是如果ModelA没有相关的modelB,它将不在结果集中。我需要它在结果集中,比如obj.modelb=None

我怎样才能做到这一点?


Tags: name模型truefieldmodelmodelsconditionclass
3条回答

使用Q组合这两个条件:

from django.db.models import Q
qs = ModelA.objects.exclude(field=condition)
qs = qs.filter(Q(modelbs__name=condition) | Q(modelbs__isnull=True))

要检查生成的SQL查询,请执行以下操作:

print qs.query.as_sql()

在类似的查询中,这将生成左外部联接。。。其中(a.val=b或a.id为空)。

看来你要面对80%的障碍了。为什么不直接使用^{}来执行子查询呢?您可以任意编写子查询,并且应该能够根据新字段进行筛选。SQL最终应该看起来像这样:

SELECT *, 
  ((EXISTS (SELECT * FROM other WHERE other.id=primary.id AND other.name='X'))
    OR (NOT EXISTS (SELECT * FROM other WHERE other.id=primary.id))) AS has_x_or_none
  FROM primary WHERE has_x_or_none=1;

尝试使用此修补程序进行自定义连接:https://code.djangoproject.com/ticket/7231

相关问题 更多 >