Django:在保留注释的同时为相关对象生成QuerySet

时间:2018-08-10 17:23:56

标签: django django-models

我有一个复杂的数据模型,其中涉及两个类似的模型:

class A(Model):
    b = ForeignKey(B)
    ...  # does not matter

class B(Model):
    ...  # does not matter

def myquery() -> QuerySet:
    qs = A.objects.filter(...).annotate(x=...)
    # The above is 46 LOC long in reality.
    # I want to return the corresponding Bs
    # plus the annotation x again, as a queryset.

我正在编写一个生成QuerySet个对象的B对象的函数。 我编写了复杂的46行代码,它们产生的QuerySet恰好是正确的A对象,并带有一个重要的注释x,我需要保留在结果中。

剩下要做的就是转换查询集,以使其返回带有重新附加了B批注的相应A对象(从x对象到1-{-1)。

如何?

1 个答案:

答案 0 :(得分:0)

这太复杂了...

这似乎可以做到:

# from django.db.models import OuterRef, Subquery
# requires Django 1.11
b_ids = qs.values_list('b', flat=True)
this_x = qs.filter(b=OuterRef('pk')) \
           .values_list('x', flat=True)
return B.objects.filter(pk__in=b_ids) \
                .annotate(x=Subquery(this_x))

不太漂亮。有更好的解决方案吗?

(P.S .:最糟糕的部分是Django文档使其很难找到该解决方案。它在某处具有所有相关信息,但组织得不好,而且对于我的口味来说常常是隐式的wrt类型。)