Take a look at the following models file:
from django.db import models
from django.contrib.contenttypes.models import ContentType
class Pointer(models.Model):
object = models.GenericForeignKey()
object_id = models.IntegerField()
content_type = models.ForeignKey(ContentType)
class A(models.Model):
pointers = models.GenericRelation(Pointer)
class B(models.Model):
pointers = models.GenericRelation(Pointer)
Let's create an A, a B and two Pointer objects:
In [1]: from test import models
In [2]: a = models.A.objects.create()
In [3]: b = models.B.objects.create()
In [4]: pa = models.Pointer.objects.create(object=a)
In [5]: pb = models.Pointer.objects.create(object=b)
In [6]: [(p.content_type, p.object_id) for p in models.Pointer.objects.all()]
Out[6]: [(<ContentType: a>, 1), (<ContentType: b>, 1)]
Now let's delete ONE object. Notice that ALL pointer objects with this object_id will be deleted. Django DOES NOT take a look at the content_type!
In [7]: a.delete()
In [8]: [(p.content_type, p.object_id) for p in models.Pointer.objects.all()]
Out[8]: []
It looks like the deletion happens in django/db/models/query.py (lines 935-940):
for f in cls._meta.many_to_many:
for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
cursor.execute("DELETE FROM %s WHERE %s IN (%s)" % \
(qn(f.m2m_db_table()), qn(f.m2m_column_name()),
','.join(['%s' for pk in pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE]])),
pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE])
The pointer class is in the object's many_to_many list, because I added "pointers = models.GenericRelation?(Pointer)" to the model:
In [9]: models.A._meta.many_to_many[0].m2m_db_table()
Out[9]: 'test_pointer'
In [10]: models.A._meta.many_to_many[0].m2m_column_name()
Out[10]: 'object_id'
I'm using Django SVN (rev 4269).