#3215: Deletion of objects with a GenericRelation(X) deletes unrelated X objects
with the same object_id!
------------------------------------------------+---------------------------
Reporter:  Thomas Steinacher <[EMAIL PROTECTED]>  |       Owner:  adrian
Type: defect | Status: new Priority: normal | Milestone: Component: Database wrapper | Version: Severity: critical | Keywords: ------------------------------------------------+---------------------------
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).

--
Ticket URL: <http://code.djangoproject.com/ticket/3215>
Django <http://code.djangoproject.org/>
The web framework for perfectionists with deadlines.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django 
updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to