Django类似于连接的查询,没有条件

时间:2018-03-15 10:45:14

标签: python django join

说我在Django中有3个模型

class Instrument(models.Model):
    ticker = models.CharField(max_length=30, unique=True, db_index=True)

class Instrument_df(models.Model):
    instrument = models.OneToOneField(
        Instrument,
        on_delete=models.CASCADE,
        primary_key=True,
    )

class Quote(models.Model):
    instrument = models.ForeignKey(Instrument, on_delete=models.CASCADE)

我只想查询与'DF'类型的乐器相对应的所有引号。在SQL中,我将在字段id上执行Quote和Instrument_df的连接。

使用Django的ORM我出来了

Quote.objects.filter(instrument__instrument_df__instrument_id__gte=-1)

我认为这可以胜任,但我看到了两个缺点:

1)我正在加入3个表格,实际上表格中不需要参与表格。

2)我不得不插入琐碎的id> -1条件,始终保持。这看起来非常人为。

如何编写此查询?

谢谢!

1 个答案:

答案 0 :(得分:2)

假设Instrument_df其他字段未在代码段中显示(否则此表只是无用且可以由Instrument中的标记替换),可能的解决方案可能是使用子查询或两个问题:

# with a subquery
dfids = Instrument_df.objects.values_list("instrument", flat=True)
Quote.objects.filter(instrument__in=dfids)

# with two queries (can be faster on MySQL)
dfids = list(Instrument_df.objects.values_list("instrument", flat=True))
Quote.objects.filter(instrument__in=dfids)

这是否会比您的实际解决方案表现更好取决于您的数据库供应商和版本(MySQL因处理子查询非常糟糕,不知道是否仍然如此)和实际内容。

但是我认为这里最好的解决方案是简单的raw query - 这样便携性较差,在架构更新时可能需要更多关注(提示:使用自定义)管理器并将此查询作为管理器方法编写,因此您只需一个事实 - 您不希望使用原始SQL查询分散视图。