Search code examples
pythondjangodjango-modelsdjango-south

Add new field to model with value based on an existing field with South


I have to add a new field "initial" to my model based on the first letter of the title.
I know i can just add the new field, override save() to automatically save the initial from now on and use South for migration like below.

models.py

class Book(models.Model):
    ...
    name = models.CharField(max_length=255, primary_key=True)
    ...
    initial = models.CharField(max_length=1, blank=True, default='')

    def save(self, *args, **kwargs):
        if self.name[0].isalpha():
            self.initial = self.name[0]
        else:
            self.initial = '#'
        super(Manga, self).save(*args, **kwargs)

But what about already existing books in the table?
Is it possible to say to South to automatically set the initial field to already existing books like above?
Or do i must write a script that updates every book to set the initial as i want?


Solution

  • you can do it by using south data migrations refer

    after creating schema migration you have to run

    ./manage.py datamigration app_name migration_name
    

    it will create a file for you as like schema migration If you open up the file, you’ll see that South has made the shell of a migration; the models definitions are there, the forwards() and backwards() functions are there, but there’s no code in either. We’ll write some code to set the initial field value over in the forwards function:

    def forwards(self, orm):
        for book in orm.Book.objects.all():
            if book.name[0].isalpha():
                book.initial = book.name[0]
            else:
                book.initial = '#'
            book.save()