Opened 13 years ago
Closed 7 years ago
#13203 closed Bug (fixed)
Deletion error of model with generic relation to inherited model
Reported by: | ramusus | Owned by: | nobody |
---|---|---|---|
Component: | contrib.contenttypes | Version: | 1.1 |
Severity: | Normal | Keywords: | content_type |
Cc: | ramusus@… | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I found that if we have 2 simple models connected by GenericRelation:
from django.contrib.comments.models import Comment class NewComment(Comment): title = models.CharField(max_length=60) class PersonWithComments(models.Model): comments = generic.GenericRelation(NewComment, object_id_field='object_pk')
It's impossible to delete PersonWithComments instance. With postgresql_psycopg2 and mysql DB drivers I always get error:
Traceback (most recent call last): File "/home/ram/PycharmProjects/m/web_site/generic/tests.py", line 75, in test_inherited_models_delete p.delete() File "/home/ram/PycharmProjects/m/web_site/django/db/models/base.py", line 610, in delete delete_objects(seen_objs, using) File "/home/ram/PycharmProjects/m/web_site/django/db/models/query.py", line 1282, in delete_objects del_query.delete_batch_related(pk_list, using=using) File "/home/ram/PycharmProjects/m/web_site/django/db/models/sql/subqueries.py", line 69, in delete_batch_related self.do_query(f.m2m_db_table(), where, using=using) File "/home/ram/PycharmProjects/m/web_site/django/db/models/sql/subqueries.py", line 27, in do_query self.get_compiler(using).execute_sql(None) File "/home/ram/PycharmProjects/m/web_site/django/db/models/sql/compiler.py", line 727, in execute_sql cursor.execute(sql, params) File "/home/ram/PycharmProjects/m/web_site/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute return self.cursor.execute(query, args) DatabaseError: column "object_pk" does not exist LINE 1: DELETE FROM "generic_newcomment" WHERE ("object_pk" IN (E'23...
With sqlite3 everithing is ok! I don't know, may be this issue related to http://code.djangoproject.com/ticket/11263, but there tells nothing about deleting.
This error appears because fields 'object_pk' and 'content_type' are not in NewComment, they are in Comment model from Comments app. And there is no checks for these fields inside ContentTypes apps.
I attach tests for recreating this issue and patch for solving it.
Attachments (3)
Change History (17)
Changed 13 years ago by
Attachment: | 13203_r12773.tests.diff added |
---|
comment:1 Changed 13 years ago by
Patch needs improvement: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
If I'm understanding the patch correctly, most of the change to m2m_table_name() is to discover the name of the model on which the object_id_field and content_type_field are located. This can be replaced by using a call to get_fields_with_model(). This returns tuples of (field, model) that describe the actual model on which fields can be found without the need to manually traverse the model heirarchy.
Changed 13 years ago by
Attachment: | 13203_r12773_2.diff added |
---|
Update patch with respect to russellm comment (ver 2)
comment:2 Changed 12 years ago by
Component: | Contrib apps → contrib.contenttypes |
---|
comment:3 Changed 12 years ago by
Type: | → Bug |
---|
comment:4 Changed 12 years ago by
Severity: | → Normal |
---|
comment:8 Changed 10 years ago by
Updated the proposed fix to current master: https://github.com/ramiro/django/compare/13203
There isn't actually need of running any test code. Just by providing a models design like the one added in the patch is enough to get the syncdb process to the test DB to crash under Postgres because of invalid DDL:
$ ~/django_test/pg84 generic_relations_regress -v2 Python version: 3.3.0 (default, Oct 7 2012, 14:43:21) [GCC 4.6.3] Importing application generic_relations_regress Creating test database for alias 'default' ('test_django_default')... Creating tables ... Creating table django_content_type Creating table auth_permission Creating table auth_group_permissions Creating table auth_group Creating table auth_user_groups Creating table auth_user_user_permissions Creating table auth_user Creating table django_site Creating table django_flatpage_sites Creating table django_flatpage Creating table django_redirect Creating table django_session Creating table django_comments Creating table django_comment_flags Creating table django_admin_log Creating table generic_relations_regress_link Creating table generic_relations_regress_place Creating table generic_relations_regress_restaurant Creating table generic_relations_regress_address Creating table generic_relations_regress_person Creating table generic_relations_regress_charlink Creating table generic_relations_regress_textlink Creating table generic_relations_regress_oddrelation1 Creating table generic_relations_regress_oddrelation2 Creating table generic_relations_regress_note Creating table generic_relations_regress_contact Creating table generic_relations_regress_organization_contacts Creating table generic_relations_regress_organization Creating table generic_relations_regress_company Creating table generic_relations_regress_reference Creating table generic_relations_regress_venue Installing custom SQL ... Installing indexes ... Traceback (most recent call last): File "django/upstream/django/db/backends/postgresql_psycopg2/base.py", line 54, in execute return self.cursor.execute(query, args) psycopg2.ProgrammingError: column "id" of relation "generic_relations_regress_reference" does not exist During handling of the above exception, another exception occurred: Traceback (most recent call last): File "django/upstream/django/core/management/commands/flush.py", line 62, in handle_noargs cursor.execute(sql) File "django/upstream/django/db/backends/postgresql_psycopg2/base.py", line 58, in execute six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2]) File "django/upstream/django/utils/six.py", line 312, in reraise raise value.with_traceback(tb) File "django/upstream/django/db/backends/postgresql_psycopg2/base.py", line 54, in execute return self.cursor.execute(query, args) django.db.utils.DatabaseError: column "id" of relation "generic_relations_regress_reference" does not exist During handling of the above exception, another exception occurred: Traceback (most recent call last): File "./runtests.py", line 323, in <module> options.failfast, args) File "./runtests.py", line 166, in django_tests failures = test_runner.run_tests(test_labels, extra_tests=extra_tests) File "django/upstream/django/test/simple.py", line 368, in run_tests old_config = self.setup_databases() File "django/upstream/django/test/simple.py", line 316, in setup_databases self.verbosity, autoclobber=not self.interactive) File "django/upstream/django/db/backends/creation.py", line 305, in create_test_db database=self.connection.alias) File "django/upstream/django/core/management/__init__.py", line 161, in call_command return klass.execute(*args, **defaults) File "django/upstream/django/core/management/base.py", line 255, in execute output = self.handle(*args, **options) File "django/upstream/django/core/management/base.py", line 385, in handle return self.handle_noargs(**options) File "django/upstream/django/core/management/commands/flush.py", line 70, in handle_noargs The full error: %s""" % (connection.settings_dict['NAME'], e)) django.core.management.base.CommandError: Database test_django_default couldn't be flushed. Possible reasons: * The database isn't running or isn't configured correctly. * At least one of the expected database tables doesn't exist. * The SQL was invalid. Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run. The full error: column "id" of relation "generic_relations_regress_reference" does not exist
comment:11 Changed 7 years ago by
Patch needs improvement: | unset |
---|
It seems this was fixed in Django 1.6 by 97774429aeb54df4c09895c07cd1b09e70201f7d. I've added a regression test.
comment:12 Changed 7 years ago by
Triage Stage: | Accepted → Ready for checkin |
---|
The added test covers the reported use cases, LGTM given the tests pass.
comment:14 Changed 7 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
tests for recreating error