2010-02-17 162 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)