Fixed #12721: Ensured objects with generic relations that use non-integer object ID fields can be deleted on PostgreSQL. Thanks much carljm for patch and Russ for review.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12353 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Karen Tracey 2010-01-29 17:58:22 +00:00
parent 11ee9746a0
commit 199cd0efca
3 changed files with 37 additions and 4 deletions

View File

@ -50,15 +50,19 @@ class DeleteQuery(Query):
for f in cls._meta.many_to_many: for f in cls._meta.many_to_many:
w1 = self.where_class() w1 = self.where_class()
db_prep_value = None
if isinstance(f, generic.GenericRelation): if isinstance(f, generic.GenericRelation):
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
field = f.rel.to._meta.get_field(f.content_type_field_name) ct_field = f.rel.to._meta.get_field(f.content_type_field_name)
w1.add((Constraint(None, field.column, field), 'exact', w1.add((Constraint(None, ct_field.column, ct_field), 'exact',
ContentType.objects.get_for_model(cls).id), AND) ContentType.objects.get_for_model(cls).id), AND)
id_field = f.rel.to._meta.get_field(f.object_id_field_name)
db_prep_value = id_field.get_db_prep_value
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
where = self.where_class() where = self.where_class()
where.add((Constraint(None, f.m2m_column_name(), f), 'in', where.add((Constraint(None, f.m2m_column_name(), f), 'in',
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), map(db_prep_value,
pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE])),
AND) AND)
if w1: if w1:
where.add(w1, AND) where.add(w1, AND)

View File

@ -40,3 +40,22 @@ class Person(models.Model):
def __unicode__(self): def __unicode__(self):
return self.name return self.name
class CharLink(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.CharField(max_length=100)
content_object = generic.GenericForeignKey()
class TextLink(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.TextField()
content_object = generic.GenericForeignKey()
class OddRelation1(models.Model):
name = models.CharField(max_length=100)
clinks = generic.GenericRelation(CharLink)
class OddRelation2(models.Model):
name = models.CharField(max_length=100)
tlinks = generic.GenericRelation(TextLink)

View File

@ -1,6 +1,6 @@
from django.test import TestCase from django.test import TestCase
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from models import Link, Place, Restaurant, Person, Address from models import Link, Place, Restaurant, Person, Address, CharLink, TextLink, OddRelation1, OddRelation2
class GenericRelationTests(TestCase): class GenericRelationTests(TestCase):
@ -30,3 +30,13 @@ class GenericRelationTests(TestCase):
qs = Person.objects.filter(addresses__zipcode='80433') qs = Person.objects.filter(addresses__zipcode='80433')
self.assertEqual(1, qs.count()) self.assertEqual(1, qs.count())
self.assertEqual('Chef', qs[0].name) self.assertEqual('Chef', qs[0].name)
def test_charlink_delete(self):
oddrel = OddRelation1.objects.create(name='clink')
cl = CharLink.objects.create(content_object=oddrel)
oddrel.delete()
def test_textlink_delete(self):
oddrel = OddRelation2.objects.create(name='tlink')
tl = TextLink.objects.create(content_object=oddrel)
oddrel.delete()