marco.santonocito
marco.santonocito

Reputation: 1703

Django: Generate slug field data for existing entries in database

Some time ago I created a Django model:

class Product(models.Model):
    name = models.CharField(verbose_name=_('Nome'), max_length=100)
    description = models.CharField(verbose_name=_('Descrizione'), blank=True, default="")

Now I would like to insert a slug field:

class Product(models.Model):
    name = models.CharField(verbose_name=_('Nome'), max_length=100)
    slug = AutoSlugField(populate_from='name', unique=True)
    description = models.CharField(verbose_name=_('Descrizione'), blank=True, default="")

My problem is that when I create a migration, Django asks me to insert a default value for the slug field.

My idea is to generate a slug during the migration for existing entries in database, there is a way to do it?

Thanks!

Upvotes: 23

Views: 6729

Answers (1)

raphv
raphv

Reputation: 1183

this is the code I have for the same situation.

models.py:

slug = AutoSlugField(null=True, default=None, unique=True, populate_from='name')

Note the null=True which is compatible with a unique field In my migrations, I'm adding a data migration by manually editing the migration file

0007_my_migration.py:

def migrate_data_forward(apps, schema_editor):
    for instance in MyModel.objects.all():
        print "Generating slug for %s"%instance
        instance.save() # Will trigger slug update

def migrate_data_backward(apps, schema_editor):
    pass

class Migration(migrations.Migration):
...

    operations = [
        migrations.AddField(
            model_name='my_model',
            name='slug',
            field=autoslug.fields.AutoSlugField(null=True, default=None, editable=False, populate_from='name', unique=True),
            preserve_default=False,
        ),
        migrations.RunPython(
            migrate_data_forward,
            migrate_data_backward,
        ),
    ]

Upvotes: 26

Related Questions