#9741 closed (duplicate)
generic relations: reverse chain of references not followed fully on delete
Reported by: | Éric St-Jean | Owned by: | aljosa |
---|---|---|---|
Component: | Contrib apps | Version: | 1.0 |
Severity: | Keywords: | genericrelation genericforeignkey | |
Cc: | eric@…, malini@…, martin@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If i have an object c, which has a genericforeignkey relation to b, which in turn has a genericforeignkey relation to a, and i delete a, b does get deleted, but not c. If i were to delete b, c does get deleted.
If these were foreign keys, the chain of reverse relations would get properly deleted, but for genericrelations, it only goes back 1 link.
from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic class A(models.Model): t = models.CharField(max_length=50) gr_b_reverse = generic.GenericRelation('GR_B') class FK_B(models.Model): """An object with a foreign key, that we'll point to an A""" fk = models.ForeignKey('A') class FK_C(models.Model): """An object with a foreign key, that we'll point to a FK_B""" fk = models.ForeignKey('FK_B') class GR_B(models.Model): """An object with a generic key, that we'll point to an A""" content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_obj = generic.GenericForeignKey(ct_field="content_type", fk_field="object_id") gr_c_reverse = generic.GenericRelation('GR_C') class GR_C(models.Model): """An object with a generic key, that we'll point to a GR_B # test proper deletion of gr_c pointing to gr_b if we delete gr_b >>> a=A.objects.create(t='foo') >>> gr_b=GR_B.objects.create(content_obj=a) >>> gr_c=GR_C.objects.create(content_obj=gr_b) >>> gr_b.delete() >>> print A.objects.all(), GR_B.objects.all(), GR_C.objects.all() [<A: A object>] [] [] >>> a.delete() # test proper deletion of gr_b pointing to a if we delete a >>> a=A.objects.create(t='foo') >>> gr_b=GR_B.objects.create(content_obj=a) >>> a.delete() >>> print A.objects.all(), GR_B.objects.all() [] [] # test proper deletion of fk_b pointing to a, fk_c pointing to b, gr_b pointing # to a, and gr_c pointing to gr_b if we delete a >>> a=A.objects.create(t='foo') >>> gr_b=GR_B.objects.create(content_obj=a) >>> gr_c=GR_C.objects.create(content_obj=gr_b) >>> fk_b=FK_B.objects.create(fk=a) >>> fk_c=FK_C.objects.create(fk=fk_b) >>> print A.objects.all(), GR_B.objects.all(), GR_C.objects.all(), FK_B.objects.all(), FK_C.objects.all() [<A: A object>] [<GR_B: GR_B object>] [<GR_C: GR_C object>] [<FK_B: FK_B object>] [<FK_C: FK_C object>] >>> a.delete() >>> print A.objects.all(), GR_B.objects.all(), GR_C.objects.all(), FK_B.objects.all(), FK_C.objects.all() [] [] [] [] [] # FAIL! we instead get: # [] [] [<GR_C: GR_C object>] [] [] """ content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_obj = generic.GenericForeignKey(ct_field="content_type", fk_field="object_id")
Attachments (1)
Change History (11)
by , 16 years ago
Attachment: | gr_test.tgz added |
---|
comment:1 by , 16 years ago
Cc: | added; removed |
---|
comment:2 by , 16 years ago
test output:
eric@pluto:~/akoha/sandbox/gr_test$ ./manage.py test gr_test_app Creating test database... Creating table auth_permission Creating table auth_group Creating table auth_user Creating table auth_message Creating table django_content_type Creating table django_session Creating table django_site Creating table gr_test_app_a Creating table gr_test_app_fk_b Creating table gr_test_app_fk_c Creating table gr_test_app_gr_b Creating table gr_test_app_gr_c Installing index for auth.Permission model Installing index for auth.Message model Installing index for gr_test_app.FK_B model Installing index for gr_test_app.FK_C model Installing index for gr_test_app.GR_B model Installing index for gr_test_app.GR_C model F ====================================================================== FAIL: Doctest: gr_test_app.models.GR_C ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/eric/django/django_src/django/test/_doctest.py", line 2180, in runTest raise self.failureException(self.format_failure(new.getvalue())) AssertionError: Failed doctest test for gr_test_app.models.GR_C File "/home/eric/akoha/sandbox/gr_test/gr_test_app/models.py", line 25, in GR_C ---------------------------------------------------------------------- File "/home/eric/akoha/sandbox/gr_test/gr_test_app/models.py", line 54, in gr_test_app.models.GR_C Failed example: print A.objects.all(), GR_B.objects.all(), GR_C.objects.all(), FK_B.objects.all(), FK_C.objects.all() Expected: [] [] [] [] [] Got: [] [] [<GR_C: GR_C object>] [] [] ---------------------------------------------------------------------- Ran 1 test in 0.041s FAILED (failures=1) Destroying test database...
comment:3 by , 16 years ago
python + django version tested with:
Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52) [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import django >>> django.VERSION (1, 1, 0, 'alpha', 0)
which is rev 9549.
also tried with (1, 0, 'final') with the exact same result.
MySQL is 5.0.51a-3ubuntu5.4
comment:4 by , 16 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:5 by , 16 years ago
milestone: | → 1.1 |
---|
comment:6 by , 16 years ago
milestone: | 1.1 → 1.2 |
---|
Pushing to 1.2. This is borderline, but at this late stage without a patch we'll have to live with this inconsistency for now. A custom Model.delete()
method can be an acceptable workaround in these cases.
comment:7 by , 16 years ago
Owner: | changed from | to
---|
comment:8 by , 15 years ago
Summary: | generic relations: reverse chain of references not followed fully yon delete → generic relations: reverse chain of references not followed fully on delete |
---|
comment:9 by , 15 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Closing as duplicate of #12953; this one was filed first, but the other already has a working patch with tests.
full project tree for test app