From f8c040e1676506e3bcba5f2744199fdcde430552 Mon Sep 17 00:00:00 2001 From: Markus Holtermann Date: Wed, 28 Jan 2015 12:13:54 +0100 Subject: [PATCH] [1.7.x] Fixed #24236 -- Treated inherited m2m fields as such if they don't define get_internal_type() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regression introduced in 3d4a826174b7a411a03be39725e60c940944a7fe Thanks IRC user ris for the report, Loïc Bistuer, Anssi Kääriäinen and Andriy Sokolovskiy for the discussion and Tim Graham for the review. --- django/db/backends/schema.py | 7 +++++-- django/db/backends/sqlite3/schema.py | 11 +++++++---- docs/releases/1.7.5.txt | 3 +++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/django/db/backends/schema.py b/django/db/backends/schema.py index 12e2ab7657..54e6e06c4f 100644 --- a/django/db/backends/schema.py +++ b/django/db/backends/schema.py @@ -3,6 +3,7 @@ import operator from django.db.backends.creation import BaseDatabaseCreation from django.db.backends.utils import truncate_name +from django.db.models.fields.related import ManyToManyField from django.db.transaction import atomic from django.utils.encoding import force_bytes from django.utils.log import getLogger @@ -358,7 +359,8 @@ class BaseDatabaseSchemaEditor(object): table instead (for M2M fields) """ # Special-case implicit M2M tables - if field.get_internal_type() == 'ManyToManyField' and field.rel.through._meta.auto_created: + if ((isinstance(field, ManyToManyField) or field.get_internal_type() == 'ManyToManyField') and + field.rel.through._meta.auto_created): return self.create_model(field.rel.through) # Get the column's definition definition, params = self.column_sql(model, field, include_default=True) @@ -402,7 +404,8 @@ class BaseDatabaseSchemaEditor(object): but for M2Ms may involve deleting a table. """ # Special-case implicit M2M tables - if field.get_internal_type() == 'ManyToManyField' and field.rel.through._meta.auto_created: + if ((isinstance(field, ManyToManyField) or field.get_internal_type() == 'ManyToManyField') and + field.rel.through._meta.auto_created): return self.delete_model(field.rel.through) # It might not actually have a column behind it if field.db_parameters(connection=self.connection)['type'] is None: diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index c5f56a04a7..0f41cb73f9 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -4,6 +4,7 @@ from decimal import Decimal from django.utils import six from django.apps.registry import Apps from django.db.backends.schema import BaseDatabaseSchemaEditor +from django.db.models.fields.related import ManyToManyField class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): @@ -69,7 +70,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): for field in create_fields: body[field.name] = field # Choose a default and insert it into the copy map - if not field.get_internal_type() == 'ManyToManyField': + if not (isinstance(field, ManyToManyField) or field.get_internal_type() == 'ManyToManyField'): mapping[field.column] = self.quote_value( self.effective_default(field) ) @@ -92,7 +93,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): del body[field.name] del mapping[field.column] # Remove any implicit M2M tables - if field.get_internal_type() == 'ManyToManyField' and field.rel.through._meta.auto_created: + if ((isinstance(field, ManyToManyField) or field.get_internal_type() == 'ManyToManyField') and + field.rel.through._meta.auto_created): return self.delete_model(field.rel.through) # Work inside a new app registry apps = Apps() @@ -171,7 +173,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): table instead (for M2M fields) """ # Special-case implicit M2M tables - if field.get_internal_type() == 'ManyToManyField' and field.rel.through._meta.auto_created: + if ((isinstance(field, ManyToManyField) or field.get_internal_type() == 'ManyToManyField') and + field.rel.through._meta.auto_created): return self.create_model(field.rel.through) self._remake_table(model, create_fields=[field]) @@ -181,7 +184,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): but for M2Ms may involve deleting a table. """ # M2M fields are a special case - if field.get_internal_type() == 'ManyToManyField': + if isinstance(field, ManyToManyField) or field.get_internal_type() == 'ManyToManyField': # For implicit M2M tables, delete the auto-created table if field.rel.through._meta.auto_created: self.delete_model(field.rel.through) diff --git a/docs/releases/1.7.5.txt b/docs/releases/1.7.5.txt index 2039c9dc4e..afce510aae 100644 --- a/docs/releases/1.7.5.txt +++ b/docs/releases/1.7.5.txt @@ -13,3 +13,6 @@ Bugfixes ``contrib.contenttypes``’s or ``contrib.auth``’s first migration (:ticket:`24075`) due to severe impact on the test performance (:ticket:`24251`) and problems in multi-database setups (:ticket:`24298`). + +* Fixed a regression that prevented custom fields inheriting from + ``ManyToManyField`` from being recognized in migrations (:ticket:`24236`).