2

Say I have a model that represents a product from my company. Each product a product number (ex. 5928523), as well as a boolean representing whether or not it is an experimental product.

class Product(models.Model):

    product_number = models.IntegerField()
    experimental = models.BooleanField(default=False)

Say I want to merge these two fields into one character field, a product ID. So an experimental product with product number 3892 would turn into "X3892" and a non-experimental product with product number 937 would simply turn into "937".

class Product(models.Model):

    product_id = models.CharField()

How would I write a database migration in Django to achieve this?

mario_sunny
  • 1,412
  • 11
  • 29
  • Use a data migration https://docs.djangoproject.com/en/1.9/topics/migrations/#data-migrations – fasouto Jan 08 '16 at 00:42
  • I have read the Django documentation on "Writing database migrations" and "Migrations" unfortunately neither the documentation nor Google has many examples. I do not know what my operations[] list should look like in my migration file for this particular application. – mario_sunny Jan 08 '16 at 00:46

1 Answers1

3

I didn't test it but something like this should work. First create a migration to add product_id.

Then create an empty migration and adapt create_product_id as you need it.

Remember to change yourappname for the name of your app.

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

def create_product_id(apps, schema_editor):
    Product = apps.get_model("yourappname", "Product")
    for product in Product.objects.all():
        p_id = str(product.product_number)
        if product.experimental:
            p_id = "X" + p_id
        product.product_id = p_id
        product.save()

class Migration(migrations.Migration):
    initial = True

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

    operations = [
        migrations.RunPython(create_product_id),
    ]
fasouto
  • 4,386
  • 3
  • 30
  • 66