Opened 9 years ago

Closed 8 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 Keryn Knight, 9 years ago

I should add, changing the InheritanceProxyChild to inherit directly from InheritanceProxyConcrete rather than the InheritanceProxy doesn't seem to affect the issue.

comment:2 by Simon Charette, 9 years ago

Triage Stage: UnreviewedAccepted

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

comment:3 by Tim Graham, 8 years ago

Resolution: duplicate
Status: newclosed

Duplicate of #18012.

Note: See TracTickets for help on using tickets.
Back to Top