che*_*art 9 django inner-join left-join
假设我有两个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)
Run Code Online (Sandbox Code Playgroud)
一个人可能属于也可能不属于公司.
我正在使用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
Jam*_*inn 14
好吧,这个问题已经过时了,很快补丁就会出现在Django中.但是在此期间,答案是http://code.djangoproject.com/ticket/10790:
解决方法:而不是
Person.objects.filter(company=None)使用
Person.objects.exclude(company__isnull=False)
它应该像这样简单:
Person.objects.filter(company_id__isnull=True)
Run Code Online (Sandbox Code Playgroud)
请注意,它的使用company_id是由ForeignKey创建的默认整数字段
编辑
抱歉,从 0.9.5 开始我就没有积极使用过 django。要么我正在考虑 1.0 之前的行为,要么我混淆了 sqlalchemy 和 Django ORM。无论哪种情况,正如评论所述,上述内容似乎都不起作用。
看起来在当前 django 中获取所需查询的唯一方法是使用.extra查询参数,该参数附带一整套警告。
Person.objects.extra(where=['company_id IS NULL'])
Run Code Online (Sandbox Code Playgroud)
请注意,这可能无法移植到所有数据库,并且它可能无法与 filter() 结合使用,以及许多可能的问题。我建议不要在整个代码中使用它,而是将其移动到 Person 上的类方法,例如:
@classmethod
def list_unaffiliated_people(cls):
return cls.objects.extra(where=['company_id IS NULL'])
Run Code Online (Sandbox Code Playgroud)
或者,只需使用正确的 ORM 查询语法并吸收可能的性能损失(您是否真的对更复杂的查询进行了基准测试以查看它是否更慢?)
| 归档时间: |
|
| 查看次数: |
10277 次 |
| 最近记录: |