Django migrations RunPython not able to call model methods

user2954587 picture user2954587 · Feb 28, 2015 · Viewed 17.1k times · Source

I'm creating a data migration using the RunPython method. However when I try to run a method on the object none are defined. Is it possible to call a method defined on a model using RunPython?

Answer

chhantyal picture chhantyal · Jun 7, 2016

Model methods are not available in migrations, including data migrations.

However there is workaround, which should be quite similar to calling model methods. You can define functions inside migrations that mimic those model methods you want to use.

If you had this method:

class Order(models.Model):
    '''
    order model def goes here
    '''

    def get_foo_as_bar(self):
        new_attr = 'bar: %s' % self.foo
        return new_attr

You can write function inside migration script like:

def get_foo_as_bar(obj):
    new_attr = 'bar: %s' % obj.foo
    return new_attr


def save_foo_as_bar(apps, schema_editor):
    old_model = apps.get_model("order", "Order")

    for obj in old_model.objects.all():
        obj.new_bar_field = get_foo_as_bar(obj)
        obj.save()

Then use it in migrations:

class Migration(migrations.Migration):

    dependencies = [
        ('order', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(save_foo_as_bar)
    ]

This way migrations will work. There will be bit of repetition of code, but it doesn't matter because data migrations are supposed to be one time operation in particular state of an application.