【问题标题】:Django: Produce QuerySet for related object while keeping an annotationDjango:为相关对象生成查询集,同时保留注释
【发布时间】:2018-08-10 17:23:56
【问题描述】:

我有一个复杂的数据模型,它涉及两个相关模型,如下所示:

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.

我正在编写一个生成 QuerySetB 对象的函数。 我已经编写了复杂的 46 行代码,这些代码生成了一个 QuerySet 恰好是正确的 A 对象以及一个重要的注释 x,我需要将其保留在结果中。

剩下要做的就是转换查询集,使其返回相应的B 对象(与A 对象一对一)并重新附加x 注释。

怎么做?

【问题讨论】:

  • 了解更多关于查询和注释的详细信息会有所帮助。一般来说,是否有什么东西无法改写B 上的查询?
  • @kristaps 也许不是不可能,但我计算注释x 的许多属性都在A 上。如果太难,我可以走@​​987654333@ 的路线,但我不喜欢我以后必须做的更繁琐的处理,以保留x

标签: django django-models


【解决方案1】:

这该死的复杂......

这似乎是:

# 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 类型不适合我的口味。)

【讨论】:

    猜你喜欢
    • 2013-12-07
    • 2023-03-19
    • 2018-01-17
    • 2021-10-17
    • 2020-07-31
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2016-10-18
    相关资源
    最近更新 更多