【问题标题】:Loop through queryset and annotate lookup value to records遍历查询集并将查找值注释到记录
【发布时间】:2021-11-30 03:32:27
【问题描述】:

我想为查询集中的每条记录查找一个值,并将该值添加到查询集中。 我有以下看法。

class InvoiceViewSet(ModelViewSet):
queryset = Invoice.objects.all()
serializer_class = InvoiceSerializer

def get_queryset(self):
    user = self.request.user
    customer_id = Customer.objects.only('ref').get(user_id=user.id)
    
    queryset = Invoice.objects.filter(supplier_id=customer_id.ref)
    
    for invoice in queryset:
        program = FunderProgramMember.objects.get(supplier=invoice.supplier_id, buyer=invoice.buyer)
        invoice.annotate(discount_rate=Value(program.discount_rate))

        return queryset

由于查询集中的发票可能有不同的折扣,我遍历查询集并添加相关折扣。

我收到以下错误:“发票”对象没有属性“注释” 我可以对查询集进行注释(这对我没有帮助,因为查询集中的记录不会都有相同的折扣)但似乎我无法对查询集中的记录进行注释。

还有其他方法可以实现吗? 即使我可以对单个记录进行注释,我也不确定这些值是否会与我的返回查询集一起传递?

编辑: 不确定这是否是最好的方法..但它似乎有效:

class InvoiceViewSet(ModelViewSet):
queryset = Invoice.objects.all()
serializer_class = InvoiceSerializer

def get_queryset(self):
    user = self.request.user
    customer_id = Customer.objects.only('ref').get(user_id=user.id)
    
        queryset = Invoice.objects.filter(supplier_id=customer_id.ref)

        for invoice in queryset:
            program = FunderProgramMember.objects.get(supplier=invoice.supplier_id, buyer=invoice.buyer)
            invoice.discount_rate = program.discount_rate

        return queryset

【问题讨论】:

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


    【解决方案1】:

    你可以像这样使用Subquery expressions来支持这个注解:

    program_discount_subquery = FunderProgramMember.objects.filter(
        supplier=OuterRef('supplier'), buyer=OuterRef('buyer')
    ).values('discount_rate')[:1]
    
    queryset = Invoice.objects.filter(
        supplier_id=customer_id.ref
    ).annotate(discount_rate=Subquery(program_discount_subquery))
    

    查询集中的每张发票都会有一个属性discount_rate

    【讨论】:

    • 谢谢@Brian Desura。我会试试你的解决方案。请检查我的帖子的编辑。我带来了一些似乎可以在不使用注释的情况下工作的东西。
    • 是的,这会起作用,但可以改进并提高效率。因为您必须按发票访问数据库才能获得相关的FunderProgramMember。因此,如果供应商有 100 张发票,则它需要 100 次数据库命中,而只有 1 次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 2020-11-06
    • 2018-01-17
    相关资源
    最近更新 更多