【问题标题】:How to create complex Left JOIN in Django如何在 Django 中创建复杂的左连接
【发布时间】:2014-04-07 09:48:18
【问题描述】:

我正在尝试使用 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)

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

谢谢

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

    你的问题是关于你的 Django 查询

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

    streettimings_isnull=True 将返回不具有 StreetTiming 关系的 Streets。所以,使用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 值。您必须使用反向关系来创建您想要的查询。

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

    您可以尝试关注,但即使它会创建一个WHERE 子句。

    Streets.objects.filter(streettimings_lookuptiming__id__gt=0).values('id')
    

    【讨论】:

    • 您的查询正在创建内部联接,同时忽略 LookupTiming。这是输出 SELECT "streets"."id" FROM "streets" INNER JOIN "street_timings" ON ("streets"."id" = "street_timings"."street_id" ) WHERE "street_timings"."lookuptiming" IS NOT NULL
    • 此查询将适用于 LookupTiming,但我想为 Streets 创建连接,而且我无法在此查询中添加更多连接模型
    • 更多模型的意思是,我只展示了两个连接模型,但实际查询包含两个以上的模型。
    • 我认为您之前的查询是正确的,但查询集正在创建一些额外的过滤器,我不知道如何排除这些过滤器。
    • 这是额外的过滤器,知道如何删除这个 WHERE "streeettimings"."lookuptiming _id" IS NULL
    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    相关资源
    最近更新 更多