【问题标题】:Create django query satisfying two conditions involving related models创建满足涉及相关模型的两个条件的django查询
【发布时间】:2021-12-02 01:38:52
【问题描述】:

我有两个模型,比如说:

class Order(models.Model):
  # ... fields

class Product(models.Model):
  quantity = models.PositiveIntegerField(null=False, blank=False, default=1)
  order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='products')
  b_product = models.ForeignKey(BaseProduct, null=False, blank=False, on_delete=models.CASCADE)

class BaseProduct(models.Model):
  type = #.... choices = [rtProduct, rtPack]

我想查询包含所有Orders 与它相关的多个Product,或者如果至少一个Product 的quantity 大于1,或者如果BaseProduct 类型为rtProduct

对于第一部分,我有这个:

queryset = Order.objects.annotate(products_count=Count('products')).filter(products_count__gt=1)

我坚持添加OR 条件以包括其他条件。 非常感谢您。

【问题讨论】:

    标签: django django-rest-framework django-queryset


    【解决方案1】:

    您可以总结数量并确定Order是否有两个或多个:

    from django.db.models import Sum
    
    Order.objects.alias(
        num_items=Sum('product__quantity')
    ).filter(num_items__gt=1)

    或在 之前使用:

    from django.db.models import Sum
    
    Order.objects.annotate(
        num_items=Sum('product__quantity')
    ).filter(num_items__gt=1)

    如果有可能有一个数量小于或等于一的Order 对象,我们应该以不同的方式执行此操作,并使用:

    from django.db.models import Count, Exists, OuterRef, Q
    
    Order.objects.alias(
        n_items=Count('product')
    ).filter(
        Q(n_item__gt=1) | Exists(
            Product.objects.filter(order_id=OuterRef('pk'), quantity__gt=1)
        )
    )

    或在之前:

    from django.db.models import Count, Exists, OuterRef, Q
    
    Order.objects.annotate(
        n_items=Count('product')
    ).filter(
        Q(n_item__gt=1) | Exists(
            Product.objects.filter(order_id=OuterRef('pk'), quantity__gt=1)
        )
    )

    【讨论】:

    • 很好的答案。我忘了提到Product 有类型并且参与了查询。我会将其添加到问题中。但我绝对使用了你的解决方案。 p_bulk_qs = Product.objects.only('order', 'quantity', 'b_product').filter(Q(quantity__gt=1) | Q(b_product__record_type=constants.rtProduct), order_id=OuterRef('pk')) 然后qs = Order.objects.annotate(n_items=Count('products')).filter(Q(n_items__gt=1) | Exists(p_bulk_qs ))
    猜你喜欢
    • 2019-04-22
    • 1970-01-01
    • 2020-01-11
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多