Question

My Blog model has AutoSlugField which uses Blog.__unicode__() method.

After data migration all Blog instances have slug set to blog-object-<number> instead of <year>-<month>-<day>. Seems like definition Blog.__unicode__() is ignored.

How could I correctly migrate Blog model?

modelfields.py:

class AutoSlugField(models.CharField):
    def pre_save(self, blog, *args, **kwargs):
        return slugify(unicode(blog))

models.py:

class Blog(models.Model):
    title = models.CharField(max_length=255)
    created = models.DateTimeField(auto_now_add=True)
    slug = AutoSlugField(max_length=50)

    def __unicode__(self):
        return self.created.strftime('%Y-%m-%d')

Migration:

from south.v2 import DataMigration

class Migration(DataMigration):
    def forwards(self, orm):
        for blog in orm.Blog.objects.all():
            blog.title = blog.title.replace('django', 'Django')
            blog.save() 
Was it helpful?

Solution 2

I have updated to South 0.7.6 and used solution from the South documentation. Simply added to_python() and get_prep_value() methods to leave slug field as is.

class AutoSlugField(models.CharField):
    def pre_save(self, blog, *args, **kwargs):
        return slugify(unicode(blog))

    def to_python(self, value):
        return value

    def get_prep_value(self, value):
        return value

OTHER TIPS

South does nothing but just add column to your table and django has no role to play in it. So when you run migration, django model save method is not called hence no pre-save method gets called. South works on database only, i.e., you can provide attributes such as default value, nullable etc. which can be set at db level. To add slug to existing records in db, create util function which would slugify your field or write a data migration.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top