Ticket #3081: genericrelation_delete.patch

File genericrelation_delete.patch, 3.0 KB (added by Alex Dedul, 18 years ago)
  • query.py

     
    909909    return joins, where, params
    910910
    911911def delete_objects(seen_objs):
     912    from django.contrib.contenttypes.models import ContentType
     913    from django.db.models.fields.generic import GenericRelation
     914
    912915    "Iterate through a list of seen classes, and remove any instances that are referred to"
    913916    qn = backend.quote_name
    914917    ordered_classes = seen_objs.keys()
     
    917920    cursor = connection.cursor()
    918921
    919922    for cls in ordered_classes:
     923        cls_content_type_params = []
     924
    920925        seen_objs[cls] = seen_objs[cls].items()
    921926        seen_objs[cls].sort()
    922927
     
    925930            dispatcher.send(signal=signals.pre_delete, sender=cls, instance=instance)
    926931
    927932        pk_list = [pk for pk,instance in seen_objs[cls]]
    928         for related in cls._meta.get_all_related_many_to_many_objects():
     933        # Filter out GenericRelation related objects because there is no m2m table
     934        # for generic relation and there is no need to delete records from it.
     935        # This also fixes issue in #2749 with deletion of both records from cls's table.
     936        for related in (obj for obj in cls._meta.get_all_related_many_to_many_objects()
     937                            if not isinstance(obj.field, GenericRelation)):
    929938            for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
    930939                cursor.execute("DELETE FROM %s WHERE %s IN (%s)" % \
    931940                    (qn(related.field.m2m_db_table()),
     
    933942                        ','.join(['%s' for pk in pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE]])),
    934943                    pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE])
    935944        for f in cls._meta.many_to_many:
     945            query_add = ""
     946
     947            if isinstance(f, GenericRelation):
     948                cls_content_type_params = cls_content_type_params or [ContentType.objects.get_for_model(cls).id]
     949                query_add = " AND %s=%%s" % f.rel.to._meta.get_field(f.content_type_field_name).column
     950
    936951            for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
    937                 cursor.execute("DELETE FROM %s WHERE %s IN (%s)" % \
    938                     (qn(f.m2m_db_table()), qn(f.m2m_column_name()),
    939                     ','.join(['%s' for pk in pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE]])),
    940                     pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE])
     952                query = "DELETE FROM %s WHERE %s IN (%s)" % \
     953                            (qn(f.m2m_db_table()), qn(f.m2m_column_name()),
     954                            ','.join(['%s' for pk in pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE]]))
     955                params = pk_list[offset:offset+GET_ITERATOR_CHUNK_SIZE]
     956                cursor.execute(query + query_add, params + cls_content_type_params)
    941957        for field in cls._meta.fields:
    942958            if field.rel and field.null and field.rel.to in seen_objs:
    943959                for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE):
Back to Top