假设我有两个Django模型Person and Company如下: -
class Company(models.Model):
name = models.CharField()
class Person(models.Model):
last_name = models.CharField(blank=True)
first_name = models.CharField()
company = models.ForeignKey(Company, null=True, blank=True)
某人可能属于也可能不属于公司。
我正在使用MySQL。我希望所有不属于任何公司的人员,即公司无效的人员。
如果我Person.objects.filter(company__isnull=True)
我得到的SQL本质上是: -
SELECT * FROM PersonTable LEFT OUTER JOIN AgencyTable ON (PersonTable.company_id = AgencyTable.id) WHERE AgencyTable.id IS NULL
如何实现以下SQL: -
SELECT * FROM PersonTable INNER JOIN AgencyTable ON (PersonTable.company_id = AgencyTable.id) WHERE AgencyTable.id IS NULL
从我从阅读Django Users邮件列表中收集的内容来看,这曾经是QuerySet Refactor之前的行为。
编辑 - 现在我看到了我的问题的亵渎!
我想说的是我只想做
SELECT * FROM PersonTable WHERE PersonTable.company_id IS NULL
答案 0 :(得分:14)
嗯,这个问题已经过时了,很快补丁就会出现在Django中。但在此期间,答案在http://code.djangoproject.com/ticket/10790:
解决方法:而不是
Person.objects.filter(company=None)
使用
Person.objects.exclude(company__isnull=False)
答案 1 :(得分:1)
应该如此简单:
Person.objects.filter(company_id__isnull=True)
请注意使用company_id
,它是ForeignKey
修改强>
对不起,我从0.9.5开始就没有主动使用django。要么我正在考虑1.0之前的行为,要么我正在混淆sqlalchemy和Django ORM。在任何一种情况下,正如评论所述,上述内容似乎无效。
看起来在当前django中获取所需查询的唯一方法是使用.extra
查询参数,该参数附带一系列警告。
Person.objects.extra(where=['company_id IS NULL'])
请注意,这可能无法移植到所有数据库,并且可能无法与filter()以及任何可能的问题一起使用。我建议不要在整个代码中使用它,而是将其移动到Person上的类方法,如:
@classmethod
def list_unaffiliated_people(cls):
return cls.objects.extra(where=['company_id IS NULL'])
或者,只需使用正确的ORM查询语法并吸收可能的性能损失(您是否真的对更复杂的查询进行基准测试,看它是否更慢?)
答案 2 :(得分:0)
Django会将NULL
视为Python的None
对象,所以:
Person.objects.filter(company = None)