summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorLoic Bistuer <loic.bistuer@gmail.com>2015-02-19 14:27:58 +0700
committerLoic Bistuer <loic.bistuer@gmail.com>2015-02-20 21:34:09 +0700
commitbed504d70bede3431a213203c13a33905d6dbf77 (patch)
treeb2216527abc707e3d48220017a107c93736b9f7a /django
parentdd0b487872de4e3ff966da51e3610bac996e44f0 (diff)
Fixed #24351, #24346 -- Changed the signature of allow_migrate().
The new signature enables better support for routing RunPython and RunSQL operations, especially w.r.t. reusable and third-party apps. This commit also takes advantage of the deprecation cycle for the old signature to remove the backward incompatibility introduced in #22583; RunPython and RunSQL won't call allow_migrate() when when the router has the old signature. Thanks Aymeric Augustin and Tim Graham for helping shape up the patch. Refs 22583.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/auth/management/__init__.py2
-rw-r--r--django/contrib/contenttypes/management.py2
-rw-r--r--django/contrib/contenttypes/migrations/0002_remove_content_type_name.py1
-rw-r--r--django/contrib/sites/management.py2
-rw-r--r--django/core/cache/backends/db.py1
-rw-r--r--django/core/management/commands/createcachetable.py2
-rw-r--r--django/core/management/commands/dumpdata.py2
-rw-r--r--django/core/management/commands/loaddata.py2
-rw-r--r--django/db/backends/base/creation.py2
-rw-r--r--django/db/migrations/operations/base.py10
-rw-r--r--django/db/migrations/operations/fields.py14
-rw-r--r--django/db/migrations/operations/models.py18
-rw-r--r--django/db/migrations/operations/special.py10
-rw-r--r--django/db/models/base.py2
-rw-r--r--django/db/utils.py35
15 files changed, 67 insertions, 38 deletions
diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py
index 44d8563c14..ea05d2b497 100644
--- a/django/contrib/auth/management/__init__.py
+++ b/django/contrib/auth/management/__init__.py
@@ -66,7 +66,7 @@ def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_
except LookupError:
return
- if not router.allow_migrate(using, Permission):
+ if not router.allow_migrate_model(using, Permission):
return
from django.contrib.contenttypes.models import ContentType
diff --git a/django/contrib/contenttypes/management.py b/django/contrib/contenttypes/management.py
index 6364c752d2..bfc25b3405 100644
--- a/django/contrib/contenttypes/management.py
+++ b/django/contrib/contenttypes/management.py
@@ -17,7 +17,7 @@ def update_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT
except LookupError:
return
- if not router.allow_migrate(using, ContentType):
+ if not router.allow_migrate_model(using, ContentType):
return
ContentType.objects.clear_cache()
diff --git a/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py b/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py
index 044fb615cf..8bd8032b41 100644
--- a/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py
+++ b/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py
@@ -33,6 +33,7 @@ class Migration(migrations.Migration):
migrations.RunPython(
migrations.RunPython.noop,
add_legacy_name,
+ hints={'model_name': 'contenttype'},
),
migrations.RemoveField(
model_name='contenttype',
diff --git a/django/contrib/sites/management.py b/django/contrib/sites/management.py
index 7c6c32d95b..5647b6a304 100644
--- a/django/contrib/sites/management.py
+++ b/django/contrib/sites/management.py
@@ -14,7 +14,7 @@ def create_default_site(app_config, verbosity=2, interactive=True, using=DEFAULT
except LookupError:
return
- if not router.allow_migrate(using, Site):
+ if not router.allow_migrate_model(using, Site):
return
if not Site.objects.using(using).exists():
diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py
index f016179491..a41b611d5b 100644
--- a/django/core/cache/backends/db.py
+++ b/django/core/cache/backends/db.py
@@ -30,6 +30,7 @@ class Options(object):
self.abstract = False
self.managed = True
self.proxy = False
+ self.swapped = False
class BaseDatabaseCache(BaseCache):
diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py
index 750e787200..4c014c88fd 100644
--- a/django/core/management/commands/createcachetable.py
+++ b/django/core/management/commands/createcachetable.py
@@ -38,7 +38,7 @@ class Command(BaseCommand):
def create_table(self, database, tablename):
cache = BaseDatabaseCache(tablename, {})
- if not router.allow_migrate(database, cache.cache_model_class):
+ if not router.allow_migrate_model(database, cache.cache_model_class):
return
connection = connections[database]
diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py
index a7c8bd7615..da1584d561 100644
--- a/django/core/management/commands/dumpdata.py
+++ b/django/core/management/commands/dumpdata.py
@@ -132,7 +132,7 @@ class Command(BaseCommand):
for model in serializers.sort_dependencies(app_list.items()):
if model in excluded_models:
continue
- if not model._meta.proxy and router.allow_migrate(using, model):
+ if not model._meta.proxy and router.allow_migrate_model(using, model):
if use_base_manager:
objects = model._base_manager
else:
diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py
index a07f6b7300..464e19ce0c 100644
--- a/django/core/management/commands/loaddata.py
+++ b/django/core/management/commands/loaddata.py
@@ -139,7 +139,7 @@ class Command(BaseCommand):
for obj in objects:
objects_in_fixture += 1
- if router.allow_migrate(self.using, obj.object.__class__):
+ if router.allow_migrate_model(self.using, obj.object.__class__):
loaded_objects_in_fixture += 1
self.models.add(obj.object.__class__)
try:
diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py
index 854e17b6c2..a5e69ceedb 100644
--- a/django/db/backends/base/creation.py
+++ b/django/db/backends/base/creation.py
@@ -107,7 +107,7 @@ class BaseDatabaseCreation(object):
def get_objects():
for model in serializers.sort_dependencies(app_list):
if (not model._meta.proxy and model._meta.managed and
- router.allow_migrate(self.connection.alias, model)):
+ router.allow_migrate_model(self.connection.alias, model)):
queryset = model._default_manager.using(self.connection.alias).order_by(model._meta.pk.name)
for obj in queryset.iterator():
yield obj
diff --git a/django/db/migrations/operations/base.py b/django/db/migrations/operations/base.py
index 557c956732..b750a1e4be 100644
--- a/django/db/migrations/operations/base.py
+++ b/django/db/migrations/operations/base.py
@@ -99,15 +99,17 @@ class Operation(object):
"""
return self.references_model(model_name, app_label)
- def allowed_to_migrate(self, connection_alias, model, hints=None):
+ def allow_migrate_model(self, connection_alias, model):
"""
Returns if we're allowed to migrate the model.
+
+ This is a thin wrapper around router.allow_migrate_model() that
+ preemptively rejects any proxy, swapped out, or unmanaged model.
"""
- # Always skip if proxy, swapped out, or unmanaged.
- if model and (model._meta.proxy or model._meta.swapped or not model._meta.managed):
+ if model._meta.proxy or model._meta.swapped or not model._meta.managed:
return False
- return router.allow_migrate(connection_alias, model, **(hints or {}))
+ return router.allow_migrate_model(connection_alias, model)
def __repr__(self):
return "<%s %s%s>" % (
diff --git a/django/db/migrations/operations/fields.py b/django/db/migrations/operations/fields.py
index 70e7a0f296..e00cfa66e2 100644
--- a/django/db/migrations/operations/fields.py
+++ b/django/db/migrations/operations/fields.py
@@ -52,7 +52,7 @@ class AddField(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
to_model = to_state.apps.get_model(app_label, self.model_name)
- if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, to_model):
from_model = from_state.apps.get_model(app_label, self.model_name)
field = to_model._meta.get_field(self.name)
if not self.preserve_default:
@@ -66,7 +66,7 @@ class AddField(Operation):
def database_backwards(self, app_label, schema_editor, from_state, to_state):
from_model = from_state.apps.get_model(app_label, self.model_name)
- if self.allowed_to_migrate(schema_editor.connection.alias, from_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, from_model):
schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
def describe(self):
@@ -117,12 +117,12 @@ class RemoveField(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
from_model = from_state.apps.get_model(app_label, self.model_name)
- if self.allowed_to_migrate(schema_editor.connection.alias, from_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, from_model):
schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
def database_backwards(self, app_label, schema_editor, from_state, to_state):
to_model = to_state.apps.get_model(app_label, self.model_name)
- if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, to_model):
from_model = from_state.apps.get_model(app_label, self.model_name)
schema_editor.add_field(from_model, to_model._meta.get_field(self.name))
@@ -184,7 +184,7 @@ class AlterField(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
to_model = to_state.apps.get_model(app_label, self.model_name)
- if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, to_model):
from_model = from_state.apps.get_model(app_label, self.model_name)
from_field = from_model._meta.get_field(self.name)
to_field = to_model._meta.get_field(self.name)
@@ -267,7 +267,7 @@ class RenameField(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
to_model = to_state.apps.get_model(app_label, self.model_name)
- if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, to_model):
from_model = from_state.apps.get_model(app_label, self.model_name)
schema_editor.alter_field(
from_model,
@@ -277,7 +277,7 @@ class RenameField(Operation):
def database_backwards(self, app_label, schema_editor, from_state, to_state):
to_model = to_state.apps.get_model(app_label, self.model_name)
- if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, to_model):
from_model = from_state.apps.get_model(app_label, self.model_name)
schema_editor.alter_field(
from_model,
diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py
index 99df8a073e..efd35f0501 100644
--- a/django/db/migrations/operations/models.py
+++ b/django/db/migrations/operations/models.py
@@ -55,12 +55,12 @@ class CreateModel(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
model = to_state.apps.get_model(app_label, self.name)
- if self.allowed_to_migrate(schema_editor.connection.alias, model):
+ if self.allow_migrate_model(schema_editor.connection.alias, model):
schema_editor.create_model(model)
def database_backwards(self, app_label, schema_editor, from_state, to_state):
model = from_state.apps.get_model(app_label, self.name)
- if self.allowed_to_migrate(schema_editor.connection.alias, model):
+ if self.allow_migrate_model(schema_editor.connection.alias, model):
schema_editor.delete_model(model)
def describe(self):
@@ -111,12 +111,12 @@ class DeleteModel(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
model = from_state.apps.get_model(app_label, self.name)
- if self.allowed_to_migrate(schema_editor.connection.alias, model):
+ if self.allow_migrate_model(schema_editor.connection.alias, model):
schema_editor.delete_model(model)
def database_backwards(self, app_label, schema_editor, from_state, to_state):
model = to_state.apps.get_model(app_label, self.name)
- if self.allowed_to_migrate(schema_editor.connection.alias, model):
+ if self.allow_migrate_model(schema_editor.connection.alias, model):
schema_editor.create_model(model)
def references_model(self, name, app_label=None):
@@ -189,7 +189,7 @@ class RenameModel(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
new_model = to_state.apps.get_model(app_label, self.new_name)
- if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, new_model):
old_model = from_state.apps.get_model(app_label, self.old_name)
# Move the main table
schema_editor.alter_db_table(
@@ -287,7 +287,7 @@ class AlterModelTable(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
new_model = to_state.apps.get_model(app_label, self.name)
- if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, new_model):
old_model = from_state.apps.get_model(app_label, self.name)
schema_editor.alter_db_table(
new_model,
@@ -347,7 +347,7 @@ class AlterUniqueTogether(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
new_model = to_state.apps.get_model(app_label, self.name)
- if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, new_model):
old_model = from_state.apps.get_model(app_label, self.name)
schema_editor.alter_unique_together(
new_model,
@@ -399,7 +399,7 @@ class AlterIndexTogether(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
new_model = to_state.apps.get_model(app_label, self.name)
- if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, new_model):
old_model = from_state.apps.get_model(app_label, self.name)
schema_editor.alter_index_together(
new_model,
@@ -448,7 +448,7 @@ class AlterOrderWithRespectTo(Operation):
def database_forwards(self, app_label, schema_editor, from_state, to_state):
to_model = to_state.apps.get_model(app_label, self.name)
- if self.allowed_to_migrate(schema_editor.connection.alias, to_model):
+ if self.allow_migrate_model(schema_editor.connection.alias, to_model):
from_model = from_state.apps.get_model(app_label, self.name)
# Remove a field if we need to
if from_model._meta.order_with_respect_to and not to_model._meta.order_with_respect_to:
diff --git a/django/db/migrations/operations/special.py b/django/db/migrations/operations/special.py
index 91261f724f..2c995c54ac 100644
--- a/django/db/migrations/operations/special.py
+++ b/django/db/migrations/operations/special.py
@@ -1,5 +1,7 @@
from __future__ import unicode_literals
+from django.db import router
+
from .base import Operation
@@ -94,13 +96,13 @@ class RunSQL(Operation):
state_operation.state_forwards(app_label, state)
def database_forwards(self, app_label, schema_editor, from_state, to_state):
- if self.allowed_to_migrate(schema_editor.connection.alias, None, hints=self.hints):
+ if router.allow_migrate(schema_editor.connection.alias, app_label, **self.hints):
self._run_sql(schema_editor, self.sql)
def database_backwards(self, app_label, schema_editor, from_state, to_state):
if self.reverse_sql is None:
raise NotImplementedError("You cannot reverse this operation")
- if self.allowed_to_migrate(schema_editor.connection.alias, None, hints=self.hints):
+ if router.allow_migrate(schema_editor.connection.alias, app_label, **self.hints):
self._run_sql(schema_editor, self.reverse_sql)
def describe(self):
@@ -171,7 +173,7 @@ class RunPython(Operation):
pass
def database_forwards(self, app_label, schema_editor, from_state, to_state):
- if self.allowed_to_migrate(schema_editor.connection.alias, None, hints=self.hints):
+ if router.allow_migrate(schema_editor.connection.alias, app_label, **self.hints):
# We now execute the Python code in a context that contains a 'models'
# object, representing the versioned models as an app registry.
# We could try to override the global cache, but then people will still
@@ -181,7 +183,7 @@ class RunPython(Operation):
def database_backwards(self, app_label, schema_editor, from_state, to_state):
if self.reverse_code is None:
raise NotImplementedError("You cannot reverse this operation")
- if self.allowed_to_migrate(schema_editor.connection.alias, None, hints=self.hints):
+ if router.allow_migrate(schema_editor.connection.alias, app_label, **self.hints):
self.reverse_code(from_state.apps, schema_editor)
def describe(self):
diff --git a/django/db/models/base.py b/django/db/models/base.py
index d906f2e461..60daa105b2 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -1549,7 +1549,7 @@ class Model(six.with_metaclass(ModelBase)):
# Find the minimum max allowed length among all specified db_aliases.
for db in settings.DATABASES.keys():
# skip databases where the model won't be created
- if not router.allow_migrate(db, cls):
+ if not router.allow_migrate_model(db, cls):
continue
connection = connections[db]
max_name_length = connection.ops.max_name_length()
diff --git a/django/db/utils.py b/django/db/utils.py
index 0480adf2dc..d038c20368 100644
--- a/django/db/utils.py
+++ b/django/db/utils.py
@@ -1,5 +1,7 @@
+import inspect
import os
import pkgutil
+import warnings
from importlib import import_module
from threading import local
@@ -7,6 +9,7 @@ from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils import six
from django.utils._os import upath
+from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.functional import cached_property
from django.utils.module_loading import import_string
@@ -276,22 +279,42 @@ class ConnectionRouter(object):
return allow
return obj1._state.db == obj2._state.db
- def allow_migrate(self, db, model, **hints):
+ def allow_migrate(self, db, app_label, **hints):
for router in self.routers:
try:
method = router.allow_migrate
except AttributeError:
# If the router doesn't have a method, skip to the next one.
- pass
+ continue
+
+ argspec = inspect.getargspec(router.allow_migrate)
+ if len(argspec.args) == 3 and not argspec.keywords:
+ warnings.warn(
+ "The signature of allow_migrate has changed from "
+ "allow_migrate(self, db, model) to "
+ "allow_migrate(self, db, app_label, model_name=None, **hints). "
+ "Support for the old signature will be removed in Django 2.0.",
+ RemovedInDjango20Warning)
+ model = hints.get('model')
+ allow = None if model is None else method(db, model)
else:
- allow = method(db, model, **hints)
- if allow is not None:
- return allow
+ allow = method(db, app_label, **hints)
+
+ if allow is not None:
+ return allow
return True
+ def allow_migrate_model(self, db, model):
+ return self.allow_migrate(
+ db,
+ model._meta.app_label,
+ model_name=model._meta.model_name,
+ model=model,
+ )
+
def get_migratable_models(self, app_config, db, include_auto_created=False):
"""
Return app models allowed to be synchronized on provided db.
"""
models = app_config.get_models(include_auto_created=include_auto_created)
- return [model for model in models if self.allow_migrate(db, model)]
+ return [model for model in models if self.allow_migrate_model(db, model)]