Migrating Existing Models¶
Existing models can be migrated to become polymorphic models. During migration, the
polymorphic_ctype field needs to be populated.
This can be done in the following steps:
Inherit your model from
PolymorphicModel.Create a Django migration file to create the
polymorphic_ctype_iddatabase column.Make sure the proper
ContentTypevalue is filled in.
Filling the content type value¶
The following code can be used to fill the value of a model:
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:
# -*- 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 makemigrations create the migration file, and include the
RunPython manually before running the migration.
Added in version 1.1.
When the model is created elsewhere, you can also use the
reset_polymorphic_ctype() function:
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)