首页 > 解决方案 > Django Annotate 和聚合行为说明。自动过滤?

问题描述

我在 DRF 中编写了一个 API,并且对查询集上的注释和聚合行为有一些疑问。所以我基本上有模型产品、生产者和模型库存。库存包含产品 fk、生产者 fk 以及数量和价格字段,以及其他不重要的字段。

我有一个列出所有库存项目的视图,并根据生产者过滤它们。我试图注释查询集以汇总和汇总所有库存项目中每个产品的数量。最初我只是直接引用了数量字段。这种方式显然有效,但我很怀疑,因为即使我没有指定它需要根据产品过滤条目,它也有效。为了安全起见,我从库存模型中访问产品模型,然后从产品返回库存做一个反向关系,并引用要汇总的数量。

我得到了相同的期望值,通过这种方式我理解了它为什么起作用,但是感觉效率低下。我需要澄清一下为什么这个简单的解决方案有效,如果我应该使用它,因为我没有过滤我的产品,但是聚合值是基于产品聚合的。

class Inventory(models.Model):
    item_ID = models.UUIDField(...)
    product = models.ForeignKey(Product, reverse = 'inventory')
    producer = models.ForeignKey(Producer)
    quantity = models.DecimalField(...)
    ...


class Product(models.Model)
    product_ID = models.UUIDField(...)
    ...


class Producer(models.Model):
    producerID = models.UUIDField(...)



class InventoryViewSet(viewsets.ModelViewSet):
    # INEFFICIENT SOLUTION
    # Here I visit product model, then reverse back to inventory model and access quantity. Results are as expected.

    def get_queryset(self):

        queryset = Inventory.objects.all()
        
        producer = self.request.query_params.get('producer')
        analytics = self.request.query_params.get('analytics')

        if analytics is not None:
               queryset = Inventory.objects.annotate(
                total_quantity = Sum('product__inventory__quantity',filter = Q(producer__online_status = True)),)

        if producer is not None:
            queryset = queryset.filter(producer = producer)
    ...

    # SIMPLE SOLUTION
    # Here I will simplyy access the quantity field directly. Results are unchanged.

    def get_queryset(self):

        queryset = Inventory.objects.all()
        producer = self.request.query_params.get('producer')
        analytics = self.request.query_params.get('analytics')

        if analytics is not None:
               queryset = Inventory.objects.annotate(
                total_quantity = Sum('quantity',filter = Q(producer__online_status = True)),)

        if producer is not None:
            queryset = queryset.filter(producer = producer)
    ...

标签: jquerydjangodjango-modelsdjango-rest-frameworkdjango-queryset

解决方案


推荐阅读