【问题标题】:Annotating a FilteredRelation on a ManyToManyField returns nothing在 ManyToManyField 上注释 FilteredRelation 不会返回任何内容
【发布时间】:2020-04-15 18:17:07
【问题描述】:

模型

class User(AbstractUser):
    pass
class Report(Model):

    user = ForeignKey (
        "User",
        related_name="reports"
    )

    shared_doctors = ManyToManyField (
        "User",
        symmetrical = False,
        related_name="shared_reports"
    )

我在模型上有更多字段,但为了缩短问题,我省略了它们。

查询

User.objects.annotate(
    shared_reports_user = FilteredRelation(
        'shared_reports',
        condition = Q(shared_reports__user=user)
    )
).annotate(
    shared_reports_user_count = Count('shared_reports_user')
)

我已将查询降低到给出意外结果的基本级别。第一个注释中的userUser 的一个实例。

Query 运行成功,但生成的 QuerySet 没有 shared_reports_user 键,尽管它有一个 shared_reports_user_count 键,其值为 0

据我从文档中了解到,FilteredRelation 采用模型上存在的一个字段,它将对其进行过滤,以及一个命名参数 condition,它将 Q 对象作为条件应用于现有字段值。这使我相信第一个注释应该返回一个 QuerySet,该 QuerySet 用 shared_reports 的子集进行注释,满足 Q 对象中指定的条件。

我确定我的数据库包含满足 Q 对象的值(我已经手动检查了数据),即使没有输出,我也希望针对键 shared_reports_user 的 QuerySet 为空。

我错过了什么吗?

【问题讨论】:

  • 我猜你必须使用像这样的F函数 Count(F('shared_reports_user'))
  • 可能,但即使在这种情况下,我的 shared_report_user 密钥也不存在。如果注解没有价值,它会消失吗?
  • 不,不是。当你使用注解 Django 执行左连接时,如果它没有值,它的值设置为 null
  • 让我知道它是否有效。
  • @Saber Solooki 我试过了,但没有任何改变

标签: django python-3.x django-models


【解决方案1】:

您可以像这样在 Django 2.0 中使用Conditional aggregation

User.objects.annotate(
shared_reports_user_count=Count('shared_reports', filter=Q(shared_reports__user_id=user.id))

【讨论】:

  • 是的,这解决了查找shared_reports_user_count的问题,但我仍然需要shared_reports_user的实际列表。
  • 这是另一个问题。但是,如果您希望每个用户都有 shared_reports,则可以使用:users = User.objects.rest_of_your_query()。 shared_reports_user_for_user1 = users[0].shared_doctors.all()
  • 是的,我发现了一些新信息。在shared_reports_user 上使用F 会展开查询集并提供一组用户,每个用户在shared_reports_user_f 中都有1 个报告。所以我的猜测是,在内部,shared_reports_user 是附加的,但不是作为属性。此外,在此之后,Count 注释给出正确的值。我接受你的回答,我会尽快发布更详细的答案以防万一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
相关资源
最近更新 更多