Suppose you have a model like this
class SampleModel(models.Model):
name = models.CharField(max_length=120)
age = models.IntegerField()
address = models.CharField(max_length=100)
and you need to change the address
to a JSONField
So you have to define a temporary field
as below
from django.db import models
from jsonfield import JSONField
class SampleModel(models.Model):
name = models.CharField(max_length=120)
age = models.IntegerField()
address = models.CharField(max_length=100)
temp_address = JSONField(default={})
Then run the commands,
python manage.py makemigrations app_name
and python manage.py migrate app_name
Then comes the role of DATA MIGRATION. What you have to do is that, run the command, python manage.py makemigrations app_name --empty
This willl create a empty migration file
in your directory.Change that file into something like this
0003_auto_20180320_1525.py (migration file)
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-03-20 15:25
from __future__ import unicode_literals
import json
from django.db import migrations
from sample.models import SampleModel
class Migration(migrations.Migration):
def forward_data_migration(apps, schema):
for sample in SampleModel.objects.all():
try:
sample.temp_address = json.loads(sample.address)
sample.save()
except json.decoder.JSONDecodeError as e:
print('Cannot convert {} object'.format(sample.pk))
def revert_migration(apps, schema):
pass
dependencies = [
('sample', '0002_samplemodel_temp_address'),
]
operations = [
migrations.RunPython(
code=forward_data_migration,
reverse_code=revert_migration
)
]
Migrate this change,then create another empty migration file as before, and write RenameField
script as below
0004_auto_20180320_1530.py
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-03-20 15:30
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sample', '0003_auto_20180320_1525'),
]
operations = [
migrations.RenameField(
model_name='samplemodel',
old_name='address',
new_name='temp_address'
),
migrations.RenameField(
model_name='samplemodel',
old_name='temp_address',
new_name='address'
)
]
Migrate this too. That's it.