简体   繁体   中英

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

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

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

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.
  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 .
  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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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