简体   繁体   English

Django外键计数过滤器

[英]Django foreign key count filter

I have the following two models: 我有以下两种模型:

Class Foo(models.model):
    param1 = ...
    param2 = ...
    ...
    paramN = ...

Class Bar(models.model):
    foo = models.ForeignKey(Foo)
    ...
    ...

GOAL: Compute a QuerySet of all instances of Foo such that more than 1 Bar instance is connected to it 目标:计算所有Foo实例的QuerySet,以便将多个Bar实例连接到它

I have been looking for a solution and this seems to work for everybody else 我一直在寻找解决方案,这似乎对其他所有人都有效

Foo.objects.annotate(num_bar=Count('bar')).filter(num_bar__gt=1)

This gave me a FieldError saying that 'bar' was not a possible field for Foo , I then tried 'bar_set' and also got the same error 这给了我一个FieldError'bar'对于Foo不是一个可能的字段,然后我尝试了'bar_set'并且也得到了同样的错误

Is there a chance I am implementing them wrong, or because they are old they are depreciated now? 我是否有可能错误地实施它们,或者因为它们很旧而现在已经贬值了? Any help would be appreciated! 任何帮助,将不胜感激!

traceback 追溯

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/manager.py", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/query.py", line 794, in annotate
    obj.query.add_annotation(annotation, alias, is_summary=False)
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 982, in add_annotation
    summarize=is_summary)
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/aggregates.py", line 20, in resolve_expression
    c = super(Aggregate, self).resolve_expression(query, allow_joins, reuse, summarize)
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/expressions.py", line 491, in resolve_expression
    c.source_expressions[pos] = arg.resolve_expression(query, allow_joins, reuse, summarize, for_save)
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/expressions.py", line 448, in resolve_expression
    return query.resolve_ref(self.name, allow_joins, reuse, summarize)
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1532, in resolve_ref
    self.get_initial_alias(), reuse)
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1471, in setup_joins
    names, opts, allow_many, fail_on_missing=True)
  File "/home/ryan/.virtualenvs/project/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1396, in names_to_path
    "Choices are: %s" % (name, ", ".join(available)))
FieldError: Cannot resolve keyword 'bar' into field. Choices are: param1, param2, param3, ..., paramN

version

my django version is 1.8.3 我的Django版本是1.8.3

There can be multiple reasons for this error, I'll try to tell the probable causes: 该错误可能有多种原因,我将尝试说明可能的原因:

  1. Recently upgrading your django version may cause the problem, clear migrations, rerun. 最近升级django版本可能会引起问题,请清除迁移,然后重新运行。
  2. Moving from local server to production server can cause this problem sometimes. 从本地服务器移动到生产服务器有时会导致此问题。
  3. Your app name can cause the problem, if it starts with "__". 如果您的应用名称以“ __”开头,则可能会引起问题。
  4. Try other simpler queries, if they work, try to change the query so that you don't use the num_model . 尝试其他更简单的查询(如果可行),请尝试更改查询,以免使用num_model
  5. also check if you can get the count of them ( the dirty way :) ): 还检查是否可以得到它们的数量(肮脏的方式:)):

    for foo in Foo.objects.all(): if foo.bar_set.count() < 2: #do sth like : foo.bar_set.get() or temp = temp + 1

as of your short description of model (not your main code), cannot find other causes. 从您对模型的简短描述(不是您的主代码)开始,找不到其他原因。 Your query should work. 您的查询应该可以。

So after trying a lot, this was a solution that worked: 因此,在尝试了很多之后,这是一个可行的解决方案:

Bar.objects.values("foo_id").annotate(Count("foo_id")).filter(pk__count__gt=1)

Not exactly sure why this worked and the other didn't, but it essentially just gets the count of Bar objects with the same foo_id and makes sure there is more than 1. 不能完全确定为什么这样做有效,而另一个则无效,但实际上,它只是获取具有相同foo_idBar对象的数量,并确保存在多个对象。

If somebody would like to explain a potential reason why this works and the other did not, that would be appreciated. 如果有人想解释一个可行的原因,而另一个却不可行,那将不胜感激。

I had the same issue by import mistake. 由于输入错误,我遇到了同样的问题。 This is solution for my use case 这是我的用例的解决方案

# from django.db.models.sql.aggregates import Count  # wrong import
from django.db.models import Count   # correct one

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM