1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
Migrating Existing Models
=========================
Existing models can be migrated to become polymorphic models. During migration, the
:attr:`~polymorphic.models.PolymorphicModel.polymorphic_ctype` field needs to be populated.
This can be done in the following steps:
#. Inherit your model from :class:`~polymorphic.models.PolymorphicModel`.
#. Create a Django migration file to create the ``polymorphic_ctype_id`` database column.
#. Make sure the proper :class:`~django.contrib.contenttypes.models.ContentType` value is filled in.
Filling the content type value
------------------------------
The following code can be used to fill the value of a model:
.. code-block:: python
from django.contrib.contenttypes.models import ContentType
from myapp.models import MyModel
new_ct = ContentType.objects.get_for_model(MyModel)
MyModel.objects.filter(polymorphic_ctype__isnull=True).update(polymorphic_ctype=new_ct)
The creation and update of the ``polymorphic_ctype_id`` column can be included in a single Django
migration. For example:
.. code-block:: python
# -*- coding: utf-8 -*-
from django.db import migrations, models
def forwards_func(apps, schema_editor):
MyModel = apps.get_model('myapp', 'MyModel')
ContentType = apps.get_model('contenttypes', 'ContentType')
new_ct = ContentType.objects.get_for_model(MyModel)
MyModel.objects.filter(polymorphic_ctype__isnull=True).update(
polymorphic_ctype=new_ct
)
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0001_initial'),
('myapp', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='mymodel',
name='polymorphic_ctype',
field=models.ForeignKey(
related_name='polymorphic_myapp.mymodel_set+',
editable=False,
to='contenttypes.ContentType',
null=True
),
),
migrations.RunPython(forwards_func, migrations.RunPython.noop),
]
It's recommended to let :django-admin:`makemigrations` create the migration file, and include the
:class:`~django.db.migrations.operations.RunPython` manually before running the migration.
.. versionadded:: 1.1
When the model is created elsewhere, you can also use the
:func:`~polymorphic.utils.reset_polymorphic_ctype` function:
.. code-block:: python
from polymorphic.utils import reset_polymorphic_ctype
from myapp.models import Base, Sub1, Sub2
reset_polymorphic_ctype(Base, Sub1, Sub2)
reset_polymorphic_ctype(Base, Sub1, Sub2, ignore_existing=True)
|