django 1.7左外连接

时间:2015-10-04 19:02:36

标签: django django-queryset django-1.7

我有一个像这样的模型

class Job(models.Model):
    description = models.CharField(max_length=255)
    user = models.ForeignKey(User)
    date = models.DateField()
    slot = models.CharField(max_length=10, choices=SLOT_CHOICES)
    location = models.ForeignKey(Location)        
    objects = JobManager()
    searches = geomodels.GeoManager()

    class Meta:
        verbose_name_plural = "Job"
        unique_together = ('date', 'slot', 'user')

    def __str__(self):
        return "{0}-{1}".format(self.user.first_name, self.date)

class Applied(models.Model):
    user = models.ForeignKey(User)
    job = models.ForeignKey(Job, null=True, blank=True)
    action_taken = models.BooleanField(default=False)
    is_declined = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = "Job Applications"
        unique_together = ('user', 'job', )

我想搜索日期范围之间的所有作业,并显示用户是否可以申请,已申请或已被拒绝。应用程序信息在应用模型中。

    jobs = Job.searches.filter(**kwargs)\
        .filter(date__range=(date_from, date_to),
                visibility=VisibilityStatus.PUBLIC,
                status=JobStatus.AVAILABLE)\
        .prefetch_related('applied_set')\
        .select_related('user__surgeryprofile__location')\
        .order_by('date')

但是我无法让它工作,它没有在数据库中对应用表进行左连接。任何建议如何让它工作。

由于

1 个答案:

答案 0 :(得分:4)

当FK NULLABLE 时,Django ORM会执行 LEFT OUTER JOIN

解决方案:只需在此FK null=True上添加job = models.ForeignKey(Job, null=True, blank=True)即可加入获取空值,Django将通过LEFT OUTER JOIN更改INNER JOIN。

这是合乎逻辑的,因为当目标表可能没有与查询中最左边的表相同的完全匹配时,左外连接是有意义的。

UPDATE:这仅适用于ForeignKey字段和select_related,不适用于带有prefetch_related的ManyToMany字段。

M2M字段的可能解决方案:

  1. 调试生成的SQL(DEBUG = True,使用logger'django.db.backends'进行日志记录)
  2. 复制并用LEFT OUTER JOIN替换INNER JOIN
  3. 执行Model.objects.raw(sql_with_left_join)
  4. https://docs.djangoproject.com/en/1.8/topics/db/sql/#performing-raw-sql-queries

    这应该给出与以前相同的结果,但是添加那些没有M2M和应用的作业。

    UPDATE2:Django中的自定义JOINS版本< = 1.5,不适用于1.6 +

    在此博客条目中找到:https://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/

    来自StackOverflow:https://stackoverflow.com/a/12943120/1090700