Django -注解,过滤和排序在一个一对多的关系上不起作用

44u64gxh  于 2023-02-05  发布在  Go
关注(0)|答案(1)|浏览(107)

我正在处理一个显示订单列表的表,该表可以根据订单的直接属性或相关模型的间接属性进行筛选和排序。这两个模型是订单和块。一个订单不能有太多的块与之关联,块总是有一个唯一的订单。

class Order(CustomBaseModel):

    date_of_order = models.DateField(default=timezone.now, verbose_name="Date of order"
    ...

class Block(CustomBaseModel):

    ...
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    ...

为了能够过滤带有或不带有块的订单,我使用以下代码注解我的查询集:

order_queryset = Order.objects.all().annotate(
            is_material_available=Case(
                    When(block__isnull=False, then=Value(True)),
                    default=Value(False),
                    output_field=BooleanField()
                ),
        )

然后在新注解上使用过滤器选项:

is_material_available = self.data["is_material_available"]

        if is_material_available == "True":
            order_queryset = order_queryset.filter(is_material_available=True)

        elif is_material_available == "False":
            order_queryset = order_queryset.filter(is_material_available=False)

使用此方法会导致以下行为:

  • 材料是否可用==“真”:只获取有订单的订单,这很好,但完全打乱了分页。假设每页的订单数是8,它将创建只有一个订单的页面,或更多。也有一些订单存在于不同的页面。
  • 材料是否可用==“假”:获取有块和没有块关联的订单,但是分页工作正常。

我尝试使用以下命令更改筛选:

order_queryset = order_queryset.filter(Exists(Block.objects.filter(order=OuterRef("pk")))

order_queryset = order_queryset.filter(block__isnull=False)

或使用该变体:

order_queryset = Order.objects.all().annotate(
            is_material_available=Count('block', distinct=True)
        )

        order_queryset = order_queryset.filter(is_material_available__gt=0)

但是结果是一样的,使用注解“is_material_available”的排序不起作用,它随机地排序订单,即使SQL查询看起来很好。
有人知道发生了什么吗?

gwbalxhn

gwbalxhn1#

我发现了问题所在,这与django的queryset框架无关,而是订单和区块是如何从两个不同的数据库更新的,不同的过滤方法都很好用。

相关问题