Opened 10 years ago
Closed 10 years ago
#24762 closed Bug (duplicate)
Proxy models with children which inherit from the proxy cannot select_related said children
| Reported by: | Keryn Knight | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | django@… | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
This has only been briefly checked on 1.7, 1.8 and django-1.9.dev20150506223347 (master), and appears to silently pass on 1.6 (because select_related previously didn't raise errors)
Given the following models:
class InheritanceProxyConcrete(models.Model):
pass
class InheritanceProxy(InheritanceProxyConcrete):
class Meta:
proxy = True
class InheritanceProxyChild(InheritanceProxy):
pass
I would expect to be able to do the following:
>>> InheritanceProxy.objects.select_related('inheritanceproxychild')
[<InheritanceProxy: InheritanceProxy object>]
# equating to something like
SELECT "tests_inheritanceproxyconcrete"."id", "tests_inheritanceproxychild"."inheritanceproxyconcrete_ptr_id" FROM "tests_inheritanceproxyconcrete" LEFT OUTER JOIN "tests_inheritanceproxychild" ON ( "tests_inheritanceproxyconcrete"."id" = "tests_inheritanceproxychild"."inheritanceproxyconcrete_ptr_id" )
however, it transpires that it doesn't work:
>>> InheritanceProxyConcrete.objects.select_related('inheritanceproxychild')
[<InheritanceProxyConcrete: InheritanceProxyConcrete object>]
>>> InheritanceProxy.objects.select_related('inheritanceproxychild')
FieldError: Invalid field name(s) given in select_related: 'inheritanceproxychild'. Choices are: (none)
>>> InheritanceProxy.objects.select_related('inheritanceproxychild_ptr')
FieldError: Invalid field name(s) given in select_related: 'inheritanceproxychild_ptr'. Choices are: (none)
Furthering the quirkiness of the problem:
>>> dir(InheritanceProxy) ['DoesNotExist', 'MultipleObjectsReturned', '__class__', ... 'inheritanceproxychild', ...] >>> InheritanceProxy.inheritanceproxychild <django.db.models.fields.related.SingleRelatedObjectDescriptor object at 0xBLAHBlAH>
I've not worked with proxies much, and certainly not recently, so there's a good probability I'm making assumptions about what functionality should be provided based on an incomplete understanding of their use cases.
I've not tested explicit OneToOnes, ForeignKeys, ManyToManys or prefetch_related, so the possibility remains that it is only implicit parentage OneToOnes which are affected.
This stems from a ticket downstream in django-model-utils regarding using a Proxy model as the parent for auto-downcasting model instances (using it's InheritanceManager)
Change History (3)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
Managed to reproduce with the following models:
from django.db import models class Concrete(models.Model): pass class Proxy(Concrete): class Meta: proxy = True class Child(Concrete): pass
>>> Concrete.objects.select_related('child') [] >>> Proxy.objects.select_related('child') FieldError: Invalid field name(s) given in select_related: 'child'. Choices are: (none)>
I should add, changing the
InheritanceProxyChildto inherit directly fromInheritanceProxyConcreterather than theInheritanceProxydoesn't seem to affect the issue.