Opened 3 years ago

Closed 3 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 3 years ago.
Here is the regressiontest patch to reproduce the bug
kill_test.2.patch (1.0 KB) - added by Natim 3 years ago.
If the GenericRelation is defined correctly no problem.

Download all attachments as: .zip

Change History (8)

Changed 3 years ago by Natim

Here is the regressiontest patch to reproduce the bug

comment:1 Changed 3 years ago by Natim

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

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 3 years ago by Natim

  • Component changed from Database layer (models, ORM) to contrib.contenttypes

Changed 3 years ago by Natim

If the GenericRelation is defined correctly no problem.

comment:3 Changed 3 years ago by Natim

  • Resolution set to invalid
  • Status changed from new to closed

comment:4 Changed 3 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 3 years ago by Natim

  • Resolution invalid deleted
  • Status changed from closed to reopened

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

comment:6 Changed 3 years ago by kmtracey

  • Resolution set to invalid
  • Status changed from reopened to closed

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