如何在Django中创建复杂的Left JOIN

时间:2014-04-07 09:48:18

标签: python django django-queryset

我正在尝试使用django

创建多模型左连接

这是我的模特

class LookupTiming(models.Model):
    day = models.CharField(max_length=7)
    time_1 = models.TimeField()
    time_2 = models.TimeField()

    class Meta:
        db_table = u'lookup_timing'

class Streets(models.Model):
    name = models.CharField(max_length=50)
    point = models.GeometryField(null=True, blank=True)
    objects = models.GeoManager()

    class Meta:
        db_table = u'streets'

    def __unicode__(self):
        return '%s' % self.name


class StreetTimings(models.Model):
    street= models.ForeignKey(Streets)
    lookuptiming = models.ForeignKey(LookupTiming)
    class Meta:
        db_table = u'street_timings'

这是我创建的查询

Streets.objects.filter(streettimings__isnull=True).filter(streettimings__lookuptiming__isnull=True).values('id')

这是上面查询的SQL输出

SELECT "streets"."id" FROM "streets"
LEFT OUTER JOIN "street_timings" ON ( "streets"."id" = "street_timings"."street_id" ) 
LEFT OUTER JOIN "street_timings" T3 ON ( "streets"."id" = T3."street_id" )
WHERE ("street_timings"."id" IS NULL AND T3."lookuptiming" IS NULL)

但我想跟随查询

select st.id from streets st
LEFT JOIN street_timings timing on timing.street_id = st.id 
LEFT JOIN lookup_timing lt on lt.id = timing.lookuptiming_id 

问题在于,django查询总是忽略 lookuptiming 模型。我想创建以下联接

Streets(id) = StreetTimings (street_id)

LookupTiming (id) = StreetTimings (lookuptiming_id)

如何为多个模型创建左连接?

谢谢

1 个答案:

答案 0 :(得分:3)

您的问题与您的Django查询有关

Streets.objects.filter(streettimings_isnull=True).filter(streettimings_lookuptiming__isnull=True).values('id')

streettimings_isnull=True将返回Streets没有StreetTiming关系的streettimings_lookuptiming__isnull=True。因此,使用Street毫无意义,因为过滤的StreetTiming对象没有相关的LookupTiming.object.values_list("streettimings__street__id", Flat=True) 关系。试试以下

LookupTiming.object.filter(streettimings__street__isnull=False).values_list("streettimings__street__id", Flat=True)

如果没有创建预期的查询,您可以尝试按照

Street.Id

这将返回所有joins值。您必须使用反向关系来创建所需的查询。

更新: 必须使用fitlering中的关系(或查询Api的其他部分),以便Django创建joins。如果您不提供任何过滤数据,django将不会创建WHERE,因为它不需要它们。

您可以尝试关注,但即使它会创建Streets.objects.filter(streettimings_lookuptiming__id__gt=0).values('id') 子句。

{{1}}
相关问题