I am trying to do the following but can't find a good solution on the documentation or on stackoverflow.
I have an existing database with ~1000 users with this model:
class Student(AbstractBaseUser):
email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
school = models.CharField(max_length=255,null=True, blank=True)
...
But I finally decided to use a separate model to handle schools :
class Student(AbstractBaseUser):
email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
school = models.ForeignKey('School')
class School(models.Model):
name = models.CharField(max_length=255,unique=True)
How can I handle all the existing students, knowing that for the future students, I will be asking the school foreignkey directly in the suscription form ?
Simplest solution wolud be to create auto migration, that will be something like this (listing only operations):
operations = [
migrations.CreateModel(
name='School',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(unique=True, max_length=255)),
],
),
migrations.AlterField(
model_name='Student',
name='school',
field=models.ForeignKey(blank=True, to='testapp.School', null=True),
),
]
I've edited model Student, so now ForeignKey can be null, you can remove null value in AlterField on the end of migration if you're sure that every Student
will have School
assigned.
Now you should edit this migration by splitting AlterField into 3 separate operations (in sequence): RenameField
(to rename existing school char field to for example school_name), AddField
(to add ForeignKey to school model) and RemoveField
(to remove old, unneeded char field).
Now, insert RunPython
operation between AddField
and RemoveField
and inside that operation run code that will create new School objects (if there is no such object in database) and assign object to your Student
.
In simple words: migration will create new model, named School
, rename old field school
to school_name
, create new field school
(ForeignKey
to School
) in model Student
, iterate through all studens creating new School
objects and assigning it into students and on last step, remove old school_name
field (previously named school
).
You can also provide reverse code into RunPython
so you can reverse that migration without data loss.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With