#16913 closed Bug (duplicate)
Admin error when trying to delete object with a GenericRelation
Reported by: | Ricky Rosario | Owned by: | Carl Meyer |
---|---|---|---|
Component: | contrib.admin | Version: | 1.3 |
Severity: | Normal | Keywords: | |
Cc: | James Socol | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If you have a model A with a GenericForeignKey and a model B with a GenericRelation to A:
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic from django.db import models class ModelA(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') class ModelB(models.Model): model_a = generic.GenericRelation(ModelA, related_name='my_related')
Create a ModelA and a related Model B:
b = ModelB.objects.create() a = b.model_a.create()
Then try to delete B in the admin and you get a 500:
Traceback: File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/core/handlers/base.py" in get_response 111. response = callback(request, *callback_args, **callback_kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/contrib/admin/options.py" in wrapper 328. return self.admin_site.admin_view(view)(*args, **kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapped_view 91. response = view_func(request, *args, **kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func 88. response = view_func(request, *args, **kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/contrib/admin/sites.py" in inner 192. return view(request, *args, **kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapper 25. return bound_func(*args, **kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapped_view 91. response = view_func(request, *args, **kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/utils/decorators.py" in bound_func 21. return func(self, *args2, **kwargs2) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/db/transaction.py" in inner 209. return func(*args, **kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/contrib/admin/options.py" in delete_view 1255. [obj], opts, request.user, self.admin_site, using) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/contrib/admin/util.py" in get_deleted_objects 76. collector.collect(objs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/contrib/admin/util.py" in collect 127. return super(NestedObjects, self).collect(objs, source_attr=source_attr, **kwargs) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/db/models/deletion.py" in collect 180. nullable=True) File "/Users/rlr/.virtualenvs/django/lib/python2.6/site-packages/django/contrib/admin/util.py" in collect 123. self.add_edge(getattr(obj, source_attr), obj) Exception Type: AttributeError at /admin/testapp/modelb/1/delete/ Exception Value: 'ModelA' object has no attribute 'my_related'
It looks like Generic Relations don't add the reverse manager to the related model (not sure if that is a bug or a feauture?) but the NestedObjects collector assumes that it will be there.
I added created a test that reproduces the issue and a potential fix: https://github.com/rlr/django/commit/8d147677fc
Change History (8)
comment:1 by , 13 years ago
Cc: | added |
---|
comment:2 by , 13 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
follow-up: 4 comment:3 by , 13 years ago
The reason I needed related_name is that, in my case (1), the GenericRelation is actually in an abstract base class and we inherit from it into two models with the same name in separate apps. If I don't set it, I get an error about collisions during model validation when starting the dev server:
forums.thread: Accessor for m2m field 'watches' clashes with related m2m field 'Watch.thread_set'. Add a related_name argument to the definition for 'watches'. kbforums.thread: Accessor for m2m field 'watches' clashes with related m2m field 'Watch.thread_set'. Add a related_name argument to the definition for 'watches'.
We have a model named Thread in two different apps. I guess that is a different bug? The validation of models probably shouldn't complain in this case.
(1) https://github.com/erikrose/django-tidings/blob/master/tidings/models.py#L118
follow-up: 5 comment:4 by , 13 years ago
Replying to r1cky:
The reason I needed related_name is that, in my case (1), the GenericRelation is actually in an abstract base class and we inherit from it into two models with the same name in separate apps. If I don't set it, I get an error about collisions during model validation when starting the dev server:
Yeah, that's a bug. If no reverse manager is actually added, there's no collision. Mind filing that one too?
Any chance you could temporarily remove one of those apps, remove the related_name, and see if the admin bug still happens?
follow-up: 6 comment:5 by , 13 years ago
Replying to carljm:
Yeah, that's a bug. If no reverse manager is actually added, there's no collision. Mind filing that one too?
Sure, will do!
Any chance you could temporarily remove one of those apps, remove the related_name, and see if the admin bug still happens?
Removing one of the apps and removing the related_name does fix the issue. I guess what I did is a workaround for the real bug :-)
comment:6 by , 13 years ago
comment:7 by , 13 years ago
Resolution: | → duplicate |
---|---|
Status: | assigned → closed |
Thanks!
Closing this as duplicate of #16920, since that's the real bug here.
Does this only occur if the
GenericRelation
has arelated_name
explicitly specified?What's the purpose of specifying
related_name
on theGenericRelation
in that example, since a reverse manager isn't added (a reverse manager doesn't really make sense, since you already havecontent_object
; in a sense, theGenericRelation
*is* the reverse manager for the GFK)?If the answers to the above two questions are "yes" and "no purpose" (I don't have time at the moment to dig into it and see), it may be that the real bug here is just that
GenericRelation
shouldn't accept a uselessrelated_name
argument.