Opened 5 years ago

Closed 5 years ago

#17310 closed Bug (invalid)

Delete an object linked to a GenericForeignKey

Reported by: Natim Owned by: nobody
Component: contrib.contenttypes Version: 1.3
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

On delete a GenericForeignKey, if you don't use object_id, you get this error :

>>> l = PageApp_Blog.objects.all()
>>> l
[<PageApp_Blog: Blog>, <PageApp_Blog: Blog>]
>>> l[1].delete()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/base.py", line 580, in delete
    collector.collect([self])
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/deletion.py", line 178, in collect
    sub_objs = relation.bulk_related_objects(new_objs, self.using)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/contrib/contenttypes/generic.py", line 189, in bulk_related_objects
    [obj.pk for obj in objs]
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/manager.py", line 141, in filter
    return self.get_query_set().filter(*args, **kwargs)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/query.py", line 550, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/query.py", line 568, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1194, in add_q
    can_reuse=used_aliases, force_having=force_having)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1069, in add_filter
    negate=negate, process_extras=process_extras)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1260, in setup_joins
    "Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'object_id' into field. Choices are: app_page_id, app_page_type, children, id, last_modif, layout, level, lft, meta_description, meta_keywords, navigation, pageapp_blog, pageapp_text, parent, placeholder_slug, plugin_order, plugins, rght, sha1, slug, title, tree_id, website

Here is the model :

class Page(MPTTModel):
    ...
    app_page_type = models.ForeignKey(ContentType,
                                      limit_choices_to = {'model__startswith': 'pageapp_'},
                                      verbose_name="page application")
    app_page_id = models.PositiveIntegerField(editable=False)
    app_page_object = generic.GenericForeignKey('app_page_type', 'app_page_id')
    ...

Attachments (2)

kill_test.patch (632 bytes) - added by Natim 5 years ago.
Here is the regressiontest patch to reproduce the bug
kill_test.2.patch (1.0 KB) - added by Natim 5 years ago.
If the GenericRelation is defined correctly no problem.

Download all attachments as: .zip

Change History (8)

Changed 5 years ago by Natim

Attachment: kill_test.patch added

Here is the regressiontest patch to reproduce the bug

comment:1 Changed 5 years ago by Natim

As you can see by running the patched test :

./runtests.py --settings=test_sqlite delete_regress
Creating test database for alias 'default'...
Creating test database for alias 'other'...
..E...s
======================================================================
ERROR: test_generic_relation_cascade (regressiontests.delete_regress.tests.DeleteCascadeTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/rhubscher/django/Django-1.3.1/tests/regressiontests/delete_regress/tests.py", line 81, in test_generic_relation_cascade
    person.delete()
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/base.py", line 580, in delete
    collector.collect([self])
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/deletion.py", line 178, in collect
    sub_objs = relation.bulk_related_objects(new_objs, self.using)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/contrib/contenttypes/generic.py", line 189, in bulk_related_objects
    [obj.pk for obj in objs]
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/manager.py", line 141, in filter
    return self.get_query_set().filter(*args, **kwargs)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/query.py", line 550, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/query.py", line 568, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1194, in add_q
    can_reuse=used_aliases, force_having=force_having)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1069, in add_filter
    negate=negate, process_extras=process_extras)
  File "/home/rhubscher/hg/modulo3/demos/jungleland/apps/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1260, in setup_joins
    "Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'object_id' into field. Choices are: app_content_type, app_object_id, awardnote, id, name, person

----------------------------------------------------------------------
Ran 7 tests in 0.266s

FAILED (errors=1, skipped=1)
Destroying test database for alias 'default'...
Destroying test database for alias 'other'...

comment:2 Changed 5 years ago by Natim

Component: Database layer (models, ORM)contrib.contenttypes

Changed 5 years ago by Natim

Attachment: kill_test.2.patch added

If the GenericRelation is defined correctly no problem.

comment:3 Changed 5 years ago by Natim

Resolution: invalid
Status: newclosed

comment:4 Changed 5 years ago by Natim

Don't forget to override the fields in the GenericRelation.

class Award(models.Model):
    name = models.CharField(max_length=25)
    app_object_id = models.PositiveIntegerField()
    app_content_type = models.ForeignKey(ContentType)
    content_object = generic.GenericForeignKey('app_content_type', 'app_object_id')

class Person(models.Model):
    name = models.CharField(max_length=25)
    awards = generic.GenericRelation(Award,
                                     content_type_field= 'app_content_type',
                                     object_id_field='app_object_id')

comment:5 Changed 5 years ago by Natim

Resolution: invalid
Status: closedreopened

Maybe instead of taking the generic names, it should try if the name exists and raise an Exception.

comment:6 Changed 5 years ago by Karen Tracey

Resolution: invalid
Status: reopenedclosed

If you are suggesting that GenericRelations should be validated and raise an exception that would more clearly indicate the problem here, that is covered by #3055. The base problem here was that the GenericRelation was defined incorrectly, that's not a Django bug, so re-closing this as invalid.

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