diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py index b738a269ec..63c44ab285 100644 --- a/django/contrib/contenttypes/generic.py +++ b/django/contrib/contenttypes/generic.py @@ -137,6 +137,11 @@ class GenericRelation(RelatedField, Field): def get_internal_type(self): return "ManyToManyField" + + def db_type(self): + # Since we're simulating a ManyToManyField, in effect, best return the + # same db_type as well. + return None class ReverseGenericRelatedObjectsDescriptor(object): """ diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 97b4ee1a47..6302416b41 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -528,7 +528,8 @@ class Query(object): self.where.add([alias, col, orig_field, lookup_type, value], connection) if negate: - self.alias_map[last[0]][ALIAS_JOIN][JOIN_TYPE] = self.LOUTER + if last: + self.alias_map[last[0]][ALIAS_JOIN][JOIN_TYPE] = self.LOUTER self.where.negate() def add_q(self, q_object): @@ -770,7 +771,7 @@ class DeleteQuery(Query): ContentType.objects.get_for_model(cls).id), AND) for offset in range(0, len(pk_list), GET_ITERATOR_CHUNK_SIZE): where = WhereNode(self) - where.add((None, f.m2m_column_name(), None, 'in', + where.add((None, f.m2m_column_name(), f, 'in', pk_list[offset : offset + GET_ITERATOR_CHUNK_SIZE]), AND) if w1: diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index 7c27fc92b3..5995f83486 100644 --- a/django/db/models/sql/where.py +++ b/django/db/models/sql/where.py @@ -87,7 +87,8 @@ class WhereNode(tree.Node): lhs = '%s.%s' % (table_alias, conn.ops.quote_name(name)) else: lhs = conn.ops.quote_name(name) - field_sql = conn.ops.field_cast_sql(field.db_type()) % lhs + db_type = field and field.db_type() or None + field_sql = conn.ops.field_cast_sql(db_type) % lhs if isinstance(value, datetime.datetime): # FIXME datetime_cast_sql() should return '%s' by default.