mirror of
https://github.com/django/django.git
synced 2025-08-03 10:34:04 +00:00
Fixed #23822 -- Added support for serializing model managers in migration
Thanks to Shai Berger, Loïc Bistuer, Simon Charette, Andrew Godwin, Tim Graham, Carl Meyer, and others for their review and input.
This commit is contained in:
parent
e37ab311fc
commit
aa5ef0d4fc
28 changed files with 608 additions and 48 deletions
|
@ -37,7 +37,7 @@ Schema Operations
|
|||
CreateModel
|
||||
-----------
|
||||
|
||||
.. class:: CreateModel(name, fields, options=None, bases=None)
|
||||
.. class:: CreateModel(name, fields, options=None, bases=None, managers=None)
|
||||
|
||||
Creates a new model in the project history and a corresponding table in the
|
||||
database to match it.
|
||||
|
@ -56,6 +56,14 @@ it can contain both class objects as well as strings in the format
|
|||
from the historical version). If it's not supplied, it defaults to just
|
||||
inheriting from the standard ``models.Model``.
|
||||
|
||||
``managers`` takes a list of 2-tuples of ``(manager_name, manager_instance)``.
|
||||
The first manager in the list will be the default manager for this model during
|
||||
migrations.
|
||||
|
||||
.. versionchanged:: 1.8
|
||||
|
||||
The ``managers`` argument was added.
|
||||
|
||||
DeleteModel
|
||||
-----------
|
||||
|
||||
|
@ -121,6 +129,15 @@ like ``permissions`` and ``verbose_name``. Does not affect the database, but
|
|||
persists these changes for :class:`RunPython` instances to use. ``options``
|
||||
should be a dictionary mapping option names to values.
|
||||
|
||||
AlterModelManagers
|
||||
------------------
|
||||
|
||||
.. versionadded:: 1.8
|
||||
|
||||
.. class:: AlterModelManagers(name, managers)
|
||||
|
||||
Alters the managers that are available during migrations.
|
||||
|
||||
AddField
|
||||
--------
|
||||
|
||||
|
|
|
@ -387,6 +387,9 @@ Migrations
|
|||
* It is now possible to have migrations (most probably :ref:`data migrations
|
||||
<data-migrations>`) for applications without models.
|
||||
|
||||
* Migrations can now :ref:`serialize model managers
|
||||
<using-managers-in-migrations>` as part of the model state.
|
||||
|
||||
Models
|
||||
^^^^^^
|
||||
|
||||
|
|
66
docs/topics/migrations.txt
Executable file → Normal file
66
docs/topics/migrations.txt
Executable file → Normal file
|
@ -286,6 +286,36 @@ modified ``__init__`` method with the old signature. So if you need a new
|
|||
argument, please create a keyword argument and add something like
|
||||
``assert kwargs.get('argument_name') is not None`` in the constructor.
|
||||
|
||||
.. _using-managers-in-migrations:
|
||||
|
||||
Model managers
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 1.8
|
||||
|
||||
You can optionally serialize managers into migrations and have them available
|
||||
in :class:`~django.db.migrations.operations.RunPython` operations. This is done
|
||||
by defining a ``use_in_migrations`` attribute on the manager class::
|
||||
|
||||
class MyManager(models.Manager):
|
||||
use_in_migrations = True
|
||||
|
||||
class MyModel(models.Model):
|
||||
objects = MyManager()
|
||||
|
||||
If you are using the :meth:`~django.db.models.from_queryset` function to
|
||||
dynamically generate a manager class, you need to inherit from the generated
|
||||
class to make it importable::
|
||||
|
||||
class MyManager(MyBaseManager.from_queryset(CustomQuerySet)):
|
||||
use_in_migrations = True
|
||||
|
||||
class MyModel(models.Model):
|
||||
objects = MyManager()
|
||||
|
||||
Please refer to the notes about :ref:`historical-models` in migrations to see
|
||||
the implications that come along.
|
||||
|
||||
Adding migrations to apps
|
||||
-------------------------
|
||||
|
||||
|
@ -326,16 +356,17 @@ you can use the :djadminopt:`--name` option::
|
|||
Historical models
|
||||
-----------------
|
||||
|
||||
When you run migrations, Django is working from historical versions of
|
||||
your models stored in the migration files. If you write Python code
|
||||
using the :class:`~django.db.migrations.operations.RunPython` operation, or if
|
||||
you have ``allow_migrate`` methods on your database routers, you will be
|
||||
exposed to these versions of your models.
|
||||
When you run migrations, Django is working from historical versions of your
|
||||
models stored in the migration files. If you write Python code using the
|
||||
:class:`~django.db.migrations.operations.RunPython` operation, or if you have
|
||||
``allow_migrate`` methods on your database routers, you will be exposed to
|
||||
these versions of your models.
|
||||
|
||||
Because it's impossible to serialize arbitrary Python code, these historical
|
||||
models will not have any custom methods or managers that you have defined.
|
||||
They will, however, have the same fields, relationships and ``Meta`` options
|
||||
(also versioned, so they may be different from your current ones).
|
||||
models will not have any custom methods that you have defined. They will,
|
||||
however, have the same fields, relationships, managers (limited to those with
|
||||
``use_in_migrations = True``) and ``Meta`` options (also versioned, so they may
|
||||
be different from your current ones).
|
||||
|
||||
.. warning::
|
||||
|
||||
|
@ -344,16 +375,17 @@ They will, however, have the same fields, relationships and ``Meta`` options
|
|||
constructors or instance methods. Plan appropriately!
|
||||
|
||||
References to functions in field options such as ``upload_to`` and
|
||||
``limit_choices_to`` are serialized in migrations, so the functions will need
|
||||
to be kept around for as long as there is a migration referencing them. Any
|
||||
:doc:`custom model fields </howto/custom-model-fields>` will also need to be
|
||||
kept, since these are imported directly by migrations.
|
||||
``limit_choices_to`` and model manager declarations with managers having
|
||||
``use_in_migrations = True`` are serialized in migrations, so the functions and
|
||||
classes will need to be kept around for as long as there is a migration
|
||||
referencing them. Any :doc:`custom model fields </howto/custom-model-fields>`
|
||||
will also need to be kept, since these are imported directly by migrations.
|
||||
|
||||
In addition, the base classes of the model are just stored as pointers,
|
||||
so you must always keep base classes around for as long as there is a migration
|
||||
that contains a reference to them. On the plus side, methods and managers
|
||||
from these base classes inherit normally, so if you absolutely need access
|
||||
to these you can opt to move them into a superclass.
|
||||
In addition, the base classes of the model are just stored as pointers, so you
|
||||
must always keep base classes around for as long as there is a migration that
|
||||
contains a reference to them. On the plus side, methods and managers from these
|
||||
base classes inherit normally, so if you absolutely need access to these you
|
||||
can opt to move them into a superclass.
|
||||
|
||||
.. _data-migrations:
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue