diff options
| author | Loic Bistuer <loic.bistuer@gmail.com> | 2015-02-19 14:27:58 +0700 |
|---|---|---|
| committer | Loic Bistuer <loic.bistuer@gmail.com> | 2015-02-20 21:34:09 +0700 |
| commit | bed504d70bede3431a213203c13a33905d6dbf77 (patch) | |
| tree | b2216527abc707e3d48220017a107c93736b9f7a /docs/topics | |
| parent | dd0b487872de4e3ff966da51e3610bac996e44f0 (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 'docs/topics')
| -rw-r--r-- | docs/topics/cache.txt | 8 | ||||
| -rw-r--r-- | docs/topics/db/multi-db.txt | 65 |
2 files changed, 46 insertions, 27 deletions
diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt index ced33bbe09..94a97d5b0e 100644 --- a/docs/topics/cache.txt +++ b/docs/topics/cache.txt @@ -226,19 +226,19 @@ operations to ``cache_replica``, and all write operations to def db_for_read(self, model, **hints): "All cache read operations go to the replica" - if model._meta.app_label in ('django_cache',): + if model._meta.app_label == 'django_cache': return 'cache_replica' return None def db_for_write(self, model, **hints): "All cache write operations go to primary" - if model._meta.app_label in ('django_cache',): + if model._meta.app_label == 'django_cache': return 'cache_primary' return None - def allow_migrate(self, db, model): + def allow_migrate(self, db, app_label, model_name=None, **hints): "Only install the cache model on primary" - if model._meta.app_label in ('django_cache',): + if app_label == 'django_cache': return db == 'cache_primary' return None diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt index 76df8610e3..e84906bb49 100644 --- a/docs/topics/db/multi-db.txt +++ b/docs/topics/db/multi-db.txt @@ -128,7 +128,7 @@ A database Router is a class that provides up to four methods: provided in the ``hints`` dictionary. Details on valid hints are provided :ref:`below <topics-db-multi-db-hints>`. - Returns None if there is no suggestion. + Returns ``None`` if there is no suggestion. .. method:: db_for_write(model, **hints) @@ -140,32 +140,53 @@ A database Router is a class that provides up to four methods: provided in the ``hints`` dictionary. Details on valid hints are provided :ref:`below <topics-db-multi-db-hints>`. - Returns None if there is no suggestion. + Returns ``None`` if there is no suggestion. .. method:: allow_relation(obj1, obj2, **hints) - Return True if a relation between obj1 and obj2 should be - allowed, False if the relation should be prevented, or None if + Return ``True`` if a relation between ``obj1`` and ``obj2`` should be + allowed, ``False`` if the relation should be prevented, or ``None`` if the router has no opinion. This is purely a validation operation, used by foreign key and many to many operations to determine if a relation should be allowed between two objects. -.. method:: allow_migrate(db, model, **hints) +.. method:: allow_migrate(db, app_label, model_name=None, **hints) - Determine if the ``model`` should have tables/indexes created in the - database with alias ``db``. Return True if the model should be - migrated, False if it should not be migrated, or None if - the router has no opinion. This method can be used to determine - the availability of a model on a given database. + Determine if the migration operation is allowed to run on the database with + alias ``db``. Return ``True`` if the operation should run, ``False`` if it + shouldn't run, or ``None`` if the router has no opinion. - Note that migrations will just silently not perform any operations - on a model for which this returns ``False``. This may result in broken - ForeignKeys, extra tables or missing tables if you change it once you - have applied some migrations. + The ``app_label`` positional argument is the label of the application + being migrated. - The value passed for ``model`` may be a - :ref:`historical model <historical-models>`, and thus not have any - custom attributes, methods or managers. You should only rely on ``_meta``. + ``model_name`` is set by most migration operations to the value of + ``model._meta.model_name`` (the lowercased version of the model + ``__name__``) of the model being migrated. Its value is ``None`` for the + :class:`~django.db.migrations.operations.RunPython` and + :class:`~django.db.migrations.operations.RunSQL` operations unless they + provide it using hints. + + ``hints`` are used by certain operations to communicate additional + information to the router. + + When ``model_name`` is set, ``hints`` normally contains the model class + under the key ``'model'``. Note that it may be a :ref:`historical model + <historical-models>`, and thus not have any custom attributes, methods, or + managers. You should only rely on ``_meta``. + + This method can also be used to determine the availability of a model on a + given database. + + Note that migrations will just silently not perform any operations on a + model for which this returns ``False``. This may result in broken foreign + keys, extra tables, or missing tables if you change it once you have + applied some migrations. + + .. versionchanged:: 1.8 + + The signature of ``allow_migrate`` has changed significantly from previous + versions. See the :ref:`deprecation notes + <deprecated-signature-of-allow-migrate>` for more details. A router doesn't have to provide *all* these methods -- it may omit one or more of them. If one of the methods is omitted, Django will skip @@ -293,15 +314,13 @@ send queries for the ``auth`` app to ``auth_db``:: return True return None - def allow_migrate(self, db, model, **hints): + def allow_migrate(self, db, app_label, model, **hints): """ Make sure the auth app only appears in the 'auth_db' database. """ - if db == 'auth_db': - return model._meta.app_label == 'auth' - elif model._meta.app_label == 'auth': - return False + if app_label == 'auth': + return db == 'auth_db' return None And we also want a router that sends all other apps to the @@ -333,7 +352,7 @@ from:: return True return None - def allow_migrate(self, db, model, **hints): + def allow_migrate(self, db, app_label, model, **hints): """ All non-auth models end up in this pool. """ |
