2010-02-17 165 views
9

比方说,我有两个Django模型人士及公司如下: -的Django ForeignKey的与空=真,内部连接和左外连接

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用户邮件列表,这曾经是QuerySet Refactor之前的行为。

编辑 - 现在我看到了我的问题的亵渎!

我想说的是,我只是想做

SELECT * FROM PersonTable WHERE PersonTable.company_id IS NULL

+0

好吧,如果这是不是你做的意义,这实际上是一个“基地”查询得到INNER加入了与其他查询,这导致怪异,重复的结果。 – chefsmart 2010-02-17 06:14:31

+0

这个问题真的是心理障碍的结果。 – chefsmart 2010-02-17 06:58:28

回答

1

它应该是简单的:

Person.objects.filter(company_id__isnull=True) 

注意使用company_id这是创建的默认整场by the ForeignKey

编辑

对不起,我从0.9.5开始就没有积极使用django。要么我在考虑1.0之前的行为,要么我正在混淆sqlalchemy和Django ORM。无论哪种情况,正如评论所述,上述情况似乎无效。

它看起来像在当前django中获得您想要的查询的唯一方法是使用.extra查询参数,它带有一整个警告列表。

Person.objects.extra(where=['company_id IS NULL']) 

请注意,这可能无法移植到所有数据库,并且可能无法与filter()和任意数量的可能问题结合使用。我不会用这个整个代码,而是将其移动到一个类方法的人似的建议:

@classmethod 
def list_unaffiliated_people(cls): 
    return cls.objects.extra(where=['company_id IS NULL']) 

或者,只要使用正确的ORM查询语法,吸了可能的性能损失(你有没有实际基准的更复杂的查询,看看它的任何慢)

+0

在shell中尝试了它,它给了我FieldError:无法将关键字'company_id'解析到字段中。选择是:company,first_name,last_name – chefsmart 2010-02-17 06:40:57

+0

Hrm。我认为可以像这样查询关键字。我想它回到了那个画板上。 – Crast 2010-02-17 07:01:01

+0

这是不可能的。 'company__id__isnull'将是有效的,但会产生几乎相同的SQL。 – ayaz 2010-02-17 12:09:58

0

Django会处理NULL如Python的None对象,以便:

Person.objects.filter(company = None) 
+0

这也给出了相同的SQL。我想Django做这件事的方式毕竟不是那么糟糕。我会专注于如何改进我的其他查找,并看看我能否解决我的问题。 – chefsmart 2010-02-18 02:56:15

14

嗯,这个问题是旧的,很快补丁将会在Django。但对于短暂的同时,得到的答复是http://code.djangoproject.com/ticket/10790

Workaround: Instead of

Person.objects.filter(company=None)

use

Person.objects.exclude(company__isnull=False)