Django查询,仅在所有子列的值均为零时返回

时间:2018-12-10 09:24:40

标签: python django python-3.x django-2.1

有没有一种简单的查询方法,如果它的所有子对象的(tradeleg)数量列都为零,则仅返回父对象(贸易)?

例如 如果trade_1有五个子项,并且其所有子项的数量字段均为“ 0”,则返回trade_1。

例如 如果trade_2有两个孩子,并且其中一个孩子在其数量字段中的值为“ 1”,则不返回trade_2。

我有这个模型:

class Trade:
    name = models.CharField(
        default='',
        max_length=50,
        blank=True,
        null=True
    )
    date = models.DateField(
        default=None,
        blank=True,
        null=True
    )



class TradeLeg(models.Model):
    trade = models.ForeignKey(
        Trade,
        on_delete=models.CASCADE
    )
    quantity = models.IntegerField(
        default=0
    )

我当前的查询:

trade = Trade.objects.filter(tradeleg__quantity = 0)

3 个答案:

答案 0 :(得分:1)

如果与之相关的任何Trade对象的数量值为0,则当前查询将保留所有TradeLeg个对象。使用exclude可以排除所有Trade个对象,其中任何相关的{ {1}}的数量值不为0:

TradeLeg

正如阿米特(Amit)指出的那样,您当前的查询无效,因为trade = Trade.objects.exclude(tradeleg__quantity__ne=0) 不是tradeleg对象的属性。使用Trade或设置ForeignKey的related_name属性。

答案 1 :(得分:0)

您好,第一件事是Trade没有TradeLed的任何引用,因此查询trade = Trade.objects.filter(tradeleg__quantity = 0)无效。

对于所需的输出,您可以先按某些条件搜索交易,例如

trade = Trade.objects.filter(name = <some name>)

并使用此交易对象来过滤TradeLeg对象,例如

tradeleg = TradeLeg.objects.filter(trade = trade, quantity != 0)
if tradeleg:
    return None
else:
    return trade

答案 2 :(得分:0)

我找到了最适合我的答案。我们可以使用注释将虚拟列添加到父对象。那么我们现在可以从中进行过滤了。

trades = Trade.objects.annotate(total_quantity=Sum('tradeleg__quantity')).filter(total_quantity__lte=0)