Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Deleting the correct related object on cascade when deleting a class that inherits a GenericRelation #526

Closed
wants to merge 1 commit into from

4 participants

Nicolas Lara Florian Apolloner Michael Elsdörfer Tim Graham
Florian Apolloner
Owner

Can you fix your patch according to the notes on the ticket? Also make sure it's mergeable, thx!

Michael Elsdörfer

This fixes the merge conflict and returns an empty queryset: https://github.com/miracle2k/django/compare/19149-generic-rel

Tim Graham
Owner

I'm going to close this as it no longer merges cleanly and @akaariai's comment on the ticket suggests that this approach isn't optimal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Nov 17, 2012
Nicolas Lara nicolaslara fixes #19149 0551751
This page is out of date. Refresh to see the latest.
4 django/contrib/contenttypes/generic.py
@@ -222,9 +222,11 @@ def bulk_related_objects(self, objs, using=DEFAULT_DB_ALIAS):
222 222 Return all objects related to ``objs`` via this ``GenericRelation``.
223 223
224 224 """
  225 + if not objs:
  226 + return []
225 227 return self.rel.to._base_manager.db_manager(using).filter(**{
226 228 "%s__pk" % self.content_type_field_name:
227   - ContentType.objects.db_manager(using).get_for_model(self.model).pk,
  229 + ContentType.objects.db_manager(using).get_for_model(objs[0].__class__).pk,
228 230 "%s__in" % self.object_id_field_name:
229 231 [obj.pk for obj in objs]
230 232 })
27 tests/regressiontests/generic_relations_regress/models.py
@@ -8,6 +8,7 @@
8 8 'CharLink', 'TextLink', 'OddRelation1', 'OddRelation2',
9 9 'Contact', 'Organization', 'Note')
10 10
  11 +
11 12 @python_2_unicode_compatible
12 13 class Link(models.Model):
13 14 content_type = models.ForeignKey(ContentType)
@@ -17,6 +18,7 @@ class Link(models.Model):
17 18 def __str__(self):
18 19 return "Link to %s id=%s" % (self.content_type, self.object_id)
19 20
  21 +
20 22 @python_2_unicode_compatible
21 23 class Place(models.Model):
22 24 name = models.CharField(max_length=100)
@@ -25,11 +27,13 @@ class Place(models.Model):
25 27 def __str__(self):
26 28 return "Place: %s" % self.name
27 29
  30 +
28 31 @python_2_unicode_compatible
29 32 class Restaurant(Place):
30 33 def __str__(self):
31 34 return "Restaurant: %s" % self.name
32 35
  36 +
33 37 @python_2_unicode_compatible
34 38 class Address(models.Model):
35 39 street = models.CharField(max_length=80)
@@ -43,6 +47,7 @@ class Address(models.Model):
43 47 def __str__(self):
44 48 return '%s %s, %s %s' % (self.street, self.city, self.state, self.zipcode)
45 49
  50 +
46 51 @python_2_unicode_compatible
47 52 class Person(models.Model):
48 53 account = models.IntegerField(primary_key=True)
@@ -52,24 +57,29 @@ class Person(models.Model):
52 57 def __str__(self):
53 58 return self.name
54 59
  60 +
55 61 class CharLink(models.Model):
56 62 content_type = models.ForeignKey(ContentType)
57 63 object_id = models.CharField(max_length=100)
58 64 content_object = generic.GenericForeignKey()
59 65
  66 +
60 67 class TextLink(models.Model):
61 68 content_type = models.ForeignKey(ContentType)
62 69 object_id = models.TextField()
63 70 content_object = generic.GenericForeignKey()
64 71
  72 +
65 73 class OddRelation1(models.Model):
66 74 name = models.CharField(max_length=100)
67 75 clinks = generic.GenericRelation(CharLink)
68 76
  77 +
69 78 class OddRelation2(models.Model):
70 79 name = models.CharField(max_length=100)
71 80 tlinks = generic.GenericRelation(TextLink)
72 81
  82 +
73 83 # models for test_q_object_or:
74 84 class Note(models.Model):
75 85 content_type = models.ForeignKey(ContentType)
@@ -77,10 +87,27 @@ class Note(models.Model):
77 87 content_object = generic.GenericForeignKey()
78 88 note = models.TextField()
79 89
  90 +
80 91 class Contact(models.Model):
81 92 notes = generic.GenericRelation(Note)
82 93
  94 +
83 95 class Organization(models.Model):
84 96 name = models.CharField(max_length=255)
85 97 contacts = models.ManyToManyField(Contact, related_name='organizations')
86 98
  99 +
  100 +class TaggedItem(models.Model):
  101 + tag = models.SlugField()
  102 + content_type = models.ForeignKey(ContentType)
  103 + object_id = models.PositiveIntegerField()
  104 + content_object = generic.GenericForeignKey('content_type', 'object_id')
  105 +
  106 +
  107 +class ParentPost(models.Model):
  108 + title = models.TextField(blank=True)
  109 + relation = generic.GenericRelation(TaggedItem)
  110 +
  111 +
  112 +class Post(ParentPost):
  113 + description = models.TextField(blank=True)
15 tests/regressiontests/generic_relations_regress/tests.py
@@ -2,7 +2,8 @@
2 2 from django.test import TestCase
3 3
4 4 from .models import (Address, Place, Restaurant, Link, CharLink, TextLink,
5   - Person, Contact, Note, Organization, OddRelation1, OddRelation2)
  5 + Person, Contact, Note, Organization, OddRelation1, OddRelation2,
  6 + TaggedItem, ParentPost, Post)
6 7
7 8
8 9 class GenericRelationTests(TestCase):
@@ -72,5 +73,17 @@ def test_q_object_or(self):
72 73 Q(notes__note__icontains=r'other note'))
73 74 self.assertTrue(org_contact in qs)
74 75
  76 + def test_inherited_models_delete(self):
  77 + """
  78 + Test that when deleting a class that inherits a GenericRelation,
  79 + the correct related object is deleted on cascade.
  80 + """
75 81
  82 + p = Post.objects.create(title="This is a title",
  83 + description="This is a description")
  84 + t = TaggedItem.objects.create(content_object=p, tag="This is a tag")
76 85
  86 + self.assertEqual(list(TaggedItem.objects.all()), [t])
  87 + self.assertEqual(list(Post.objects.all()), [p])
  88 + p.delete()
  89 + self.assertEqual(list(TaggedItem.objects.all()), [])

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.