Skip to main content
 首页 » 编程设计

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

2024年08月27日31JustinYoung

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

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

谢谢

请您参考如下方法:

你的问题是关于你的 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) 

如果它没有创建预期的查询,yuou 可能会尝试以下

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

这将返回所有 Street.Id 值。您必须使用反向关系来创建您想要的查询。

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

您可以尝试跟随,但即使这样也会创建一个 WHERE 子句。

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