[Django] #27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django 1.10(.3)

97 views
Skip to first unread message

Django

unread,
Nov 8, 2016, 2:19:35 AM11/8/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: coldib | Owner: nobody
Type: Bug | Status: new
Component: | Version: 1.10
Uncategorized | Keywords: GenericRelation,
Severity: Normal | Abstract, ContentFramework
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Creating the following models does work in Django 1.9, however in Django
1.10 the following error is raised **as soon as the class that inherits is
created** (in the example as soon as class DetailTest is created):

{{{
<function make_generic_foreign_order_accessors at 0x7f5444873488>:
(models.E022) <function make_generic_foreign_order_accessors at
0x7f5444873488> contains a lazy reference to testac.abstractmaster, but
app 'testac' doesn't provide model 'abstractmaster'.
testac.DetailTest.relatedMasterModel: (fields.E307) The field
testac.DetailTest.relatedMasterModel was declared with a lazy reference to
'testac.abstractmaster', but app 'testac' doesn't provide model
'abstractmaster'.
}}}


**models.py**

{{{
from __future__ import unicode_literals

from django.db import models

from django.contrib.contenttypes.fields import GenericForeignKey,
GenericRelation
from django.contrib.contenttypes.models import ContentType


class AbstractMaster (models.Model):
class Meta: abstract=True

detailModel_type = models.ForeignKey(ContentType, blank=True,
null=True)
detailModel_id = models.PositiveIntegerField(blank=True, null=True)
detail_Model = GenericForeignKey('detailModel_type', 'detailModel_id')

class AbstractDetail (models.Model):
class Meta: abstract=True

masterModel_type = models.ForeignKey(ContentType, blank=True,
null=True)
masterModel_id = models.PositiveIntegerField(blank=True, null=True)
master_Model = GenericForeignKey('masterModel_type', 'masterModel_id')

relatedMasterModel = GenericRelation(AbstractMaster,
object_id_field='detailModel_id', content_type_field='detailModel_id',
related_query_name='%(app_label)s_%(class)s_detail_model')

class MasterTest (AbstractMaster):
pass

class DetailTest (AbstractDetail):
pass
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27460>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 8, 2016, 7:37:24 PM11/8/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: nobody
Type: Bug | Status: new
Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* cc: Alex Hill (added)
* component: Uncategorized => Core (Other)


Comment:

Alex, was this an oversight in 2ff7ef15b0a1d41e3f121e96cb72a383863046c0?

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:1>

Django

unread,
Nov 8, 2016, 11:17:28 PM11/8/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: nobody
Type: Bug | Status: new

Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Alex Hill):

I'm pretty sure this is just a more explicit failure of something that
didn't work before. You can create the models as described, but see it
blow up in 1.9 in the sample below when you actually try to use it.

I might be thinking about this wrong, but what would a GenericRelation to
an abstract model mean? Which model would queries on the field yield
instances of?

Wolfgang - can you provide an example of how you were successfully using
this in 1.9?

{{{
>>> from ag.models import MasterTest, DetailTest
>>> mt = MasterTest.objects.create()
>>> dt = DetailTest.objects.create()
>>> mt.detail_Model = dt
>>> mt.save()
>>> dt.master_Model = mt
>>> dt.save()
>>>
>>> dt.relatedMasterModel.all()
Traceback (most recent call last):
File "/home/alexh/djexperiments/env/lib/python3.5/site-
packages/django/core/management/commands/shell.py", line 69, in handle
self.run_shell(shell=options['interface'])
File "/home/alexh/djexperiments/env/lib/python3.5/site-
packages/django/core/management/commands/shell.py", line 61, in run_shell
raise ImportError
ImportError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/alexh/djexperiments/env/lib/python3.5/site-
packages/django/db/models/fields/related_descriptors.py", line 468, in
__get__
return self.related_manager_cls(instance)
File "/home/alexh/djexperiments/env/lib/python3.5/site-
packages/django/utils/functional.py", line 33, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/alexh/djexperiments/env/lib/python3.5/site-
packages/django/contrib/contenttypes/fields.py", line 448, in
related_manager_cls
self.rel.model._default_manager.__class__,
AttributeError: type object 'AbstractMaster' has no attribute
'_default_manager'
>>>
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:2>

Django

unread,
Nov 9, 2016, 1:22:55 PM11/9/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: nobody
Type: Bug | Status: new

Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Wolfgang Grim):

Hmm I also don't get it to run now - But I can explain what I want to
achieve:

models.py
{{{
from __future__ import unicode_literals

from django.db import models

from django.contrib.contenttypes.fields import GenericForeignKey,
GenericRelation
from django.contrib.contenttypes.models import ContentType


class AbstractMaster (models.Model):
class Meta: abstract=True

detailModel_type = models.ForeignKey(ContentType, blank=True,
null=True)
detailModel_id = models.PositiveIntegerField(blank=True, null=True)
detail_Model = GenericForeignKey('detailModel_type', 'detailModel_id')

class AbstractDetail (models.Model):
class Meta: abstract=True

name = models.CharField (max_length=255, null=True)


masterModel_type = models.ForeignKey(ContentType, blank=True,
null=True)
masterModel_id = models.PositiveIntegerField(blank=True, null=True)
master_Model = GenericForeignKey('masterModel_type', 'masterModel_id')

relatedMasterModel = GenericRelation(AbstractMaster,
object_id_field='detailModel_id', content_type_field='detailModel_id',
related_query_name='%(app_label)s_%(class)s_detail_model')

class MasterTest (AbstractMaster):
pass

class DetailTest (AbstractDetail):
pass
}}}


python manage.py shell
{{{
from testac.models import MasterTest, DetailTest
mt = MasterTest.objects.create()
dt = DetailTest.objects.create(name="Test")


mt.detail_Model = dt
mt.save()
dt.master_Model = mt
dt.save()

mt.detail_Model.name
# Out[8]: 'Test' (So this is working)

MasterTest.objects.filter(detail_Model__name="Test")
# Throws: FieldError: Field 'detail_Model' does not generate an automatic
reverse relation and therefore cannot be used for reverse querying. If it
is a GenericForeignKey, consider adding a GenericRelation.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:3>

Django

unread,
Nov 9, 2016, 2:45:11 PM11/9/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: nobody
Type: Bug | Status: new

Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

If the use case is invalid, perhaps the error message about " app 'testac'
doesn't provide model 'abstractmaster'" could be improved with an
explanation about abstract models?

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:4>

Django

unread,
Nov 9, 2016, 10:28:36 PM11/9/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: nobody
Type: Bug | Status: new

Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Alex Hill):

Hi Tim,

The message when you try to declare a normal relation to an abstract model
is this:

{{{
ag.DetailTest.something: (fields.E300) Field defines a relation with model
'AbstractSomething', which is either not installed, or is abstract.
}}}

I'll look at how we can catch the GenericRelation case in the same branch,
because that's much nicer.

Wolfgang: the trend in Django is to alert the user to problems earlier
rather than later, and I'm quite sure that's what's happening here. There
hasn't actually been any change in functionality since 1.9.

When you do `MasterTest.objects.filter(detail_Model__name="Test")`, Django
doesn't know which table to look for a matching "name" field in, because
the relation is generic and that information is stored in the database. It
would technically be possible to implement this, and return a
heterogeneous collection of objects that inherit from the abstract model,
but the code would be messy, it would be completely new ground for the
Django ORM, and for such a corner case I just don't think it would be
accepted.

There are third-party libraries that provide more polymorphism in Django,
and I'd recommend looking into those to see if they meet your needs. Here
are a couple:

https://django-polymorphic.readthedocs.io/en/stable/
https://django-model-
utils.readthedocs.io/en/latest/managers.html#inheritancemanager

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:5>

Django

unread,
Nov 9, 2016, 10:29:50 PM11/9/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: Alex Hill
Type: Bug | Status: assigned

Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Alex Hill):

* owner: nobody => Alex Hill
* status: new => assigned


Comment:

Tim: should I accept this and change its description to indicate that the
error message needs improvement, or close it and create a new ticket?

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:6>

Django

unread,
Nov 10, 2016, 3:28:41 AM11/10/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: Alex Hill
Type: Bug | Status: assigned
Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Wolfgang Grim):

Hello! At least the following should work right?

{{{
from __future__ import unicode_literals

from django.db import models

from django.contrib.contenttypes.fields import GenericForeignKey,
GenericRelation
from django.contrib.contenttypes.models import ContentType

class AbstractDetail (models.Model):
class Meta: abstract=True

relatedTrackModel = GenericRelation("TrackDetail",


object_id_field='detailModel_id', content_type_field='detailModel_id',
related_query_name='%(app_label)s_%(class)s_detail_model')

class TrackDetail (models.Model):


detailModel_type = models.ForeignKey(ContentType, blank=True,
null=True)
detailModel_id = models.PositiveIntegerField(blank=True, null=True)
detail_Model = GenericForeignKey('detailModel_type', 'detailModel_id')

added = models.DateTimeField(null=True)


class DetailTest (AbstractDetail):
name = models.CharField(max_length=200, null=True)
pass
}}}

shell:
{{{
from testac.models import DetailTest, TrackDetail
from django.utils import timezone


dt = DetailTest.objects.create(name="name1")
track = TrackDetail.objects.create()
track.detail_Model=dt
track.added = timezone.now()

x =
TrackDetail.objects.filter(testac_detailtest_detail_model__name="name")
FieldError: Cannot resolve keyword 'testac_detailtest_detail_model' into
field. Choices are: %(app_label)s_%(class)s_detail_model, added,
detailModel_id, detailModel_type, detailModel_type_id, detail_Model, id
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:7>

Django

unread,
Nov 10, 2016, 3:48:24 AM11/10/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: Alex Hill
Type: Bug | Status: assigned
Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Alex Hill):

That could potentially work, I think.

Does it work in 1.9, or is this a new feature?

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:8>

Django

unread,
Nov 10, 2016, 12:14:19 PM11/10/16
to django-...@googlegroups.com
#27460: GenericRelation doesn't work from AbstractClass to AbstractClass in Django
1.10(.3)
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: Alex Hill
Type: Bug | Status: assigned
Component: Core (Other) | Version: 1.10
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage:
Abstract, ContentFramework | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Wolfgang Grim):

It doesn't work neither in 1.9 nor in 1.10 I receive

{{{


FieldError: Cannot resolve keyword 'testac_detailtest_detail_model' into
field. Choices are: %(app_label)s_%(class)s_detail_model, added,
detailModel_id, detailModel_type, detailModel_type_id, detail_Model, id
}}}

using dt.relatedTrackModel() I get an empty Queryset

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:9>

Django

unread,
Nov 22, 2016, 2:49:53 PM11/22/16
to django-...@googlegroups.com
#27460: Allow declaring a GenericRelation from an abstract model to another
abstract model

-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: Alex Hill
Type: New feature | Status: assigned
Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage: Accepted
Abstract, ContentFramework |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* type: Bug => New feature
* component: Core (Other) => Database layer (models, ORM)
* stage: Unreviewed => Accepted


Comment:

Tentatively accepting and retitling based on a skim of the issue.

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:10>

Django

unread,
Mar 21, 2023, 5:33:56 AM3/21/23
to django-...@googlegroups.com
#27460: Allow declaring a GenericRelation from an abstract model to another
abstract model
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: (none)
Type: New feature | Status: new

Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage: Accepted
Abstract, ContentFramework |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* owner: Alex Hill => (none)
* status: assigned => new


--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:11>

Django

unread,
Mar 11, 2024, 8:10:35 AM3/11/24
to django-...@googlegroups.com
#27460: Allow declaring a GenericRelation from an abstract model to another
abstract model
-------------------------------------+-------------------------------------
Reporter: Wolfgang Grim | Owner: (none)
Type: New feature | Status: new
Component: Database layer | Version: 1.10
(models, ORM) |
Severity: Normal | Resolution:
Keywords: GenericRelation, | Triage Stage: Accepted
Abstract, ContentFramework |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sage Abdullah):

* cc: Sage Abdullah (added)

--
Ticket URL: <https://code.djangoproject.com/ticket/27460#comment:12>
Reply all
Reply to author
Forward
0 new messages