Opened 8 years ago

Last modified 8 years ago

#26797 closed Bug

Reverse `related_name` of a proxy not accessible to inherited proxies — at Initial Version

Reported by: Maxime Lorant Owned by: nobody
Component: Database layer (models, ORM) Version: 1.9
Severity: Normal Keywords: related_name reverse relation
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Taken the following example (not real world use case, but it is somewhat equivalent of something I encountered):

from django.db import models


class Animal(models.Model):
    name = models.CharField("animal name", max_length=255, blank=True, null=False)

class Mammal(Animal):
    class Meta:
        proxy = True

class Cat(Mammal):
    class Meta:
        proxy = True

class Dog(Mammal):
    class Meta:
        proxy = True

class TrueFriendship(models.Model):
    mammal = models.ForeignKey(Mammal, related_name="dog_friends")
    dog = models.ForeignKey(Dog, related_name="mammal_friends")

I want to get the number of friends of a queryset of cats. However, doing this in a shell results in an exception:

>>> from nature.models import *
>>> cat = Cat.objects.create(name="cat1")
>>> dog = Dog.objects.create(name="dog1")
>>> TrueFriendship.objects.create(cat=cat, dog=dog)
>>> Cat.objects.annotate(nb_dog_friends=models.Count('dog_friends'))
Traceback (most recent call last):
  File "/data/.virtualenvs/bugproxy/local/lib/python2.7/site-packages/django/db/models/manager.py", line 122, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
[...]
  File "/data/.virtualenvs/bugproxy/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1330, in names_to_path
    "Choices are: %s" % (name, ", ".join(available)))
FieldError: Cannot resolve keyword 'dog_friends' into field. Choices are: id, name

(Full traceback attached in a file) However, the same query using the Mammal proxy works and the reverse relation is available on single object:

>>> Mammal.objects.annotate(nb_dog_friends=models.Count('dog_friends')).first().nb_dog_friends
1
>>> Cat.objects.first().dog_friends.all()
[<TrueFriendship: TrueFriendship object>]

Something is inconsistent here: I would expect to have access to dog_friends in both cases (on a model instance and a queryset)

Change History (1)

by Maxime Lorant, 8 years ago

Attachment: traceback.txt added
Note: See TracTickets for help on using tickets.
Back to Top