I have a save override method in my model class, which generates a new slug each time an object is saved.
def save(self, *args, **kwargs):
if self.column2:
self.slug = slugify(self.column1 + " " + self.column2)
else:
self.slug = slugify(self.column1)
print slug
super(MyModel, self).save(*args, **kwargs)
When I try to create a new object by logging into the python shell, I see the save method is being invoked.
python manage.py shell
>>> MyModel(column1="test",column2="2015").save()
slug is test-2015
However when I am running a migration, this save override method is not being called. Here's part of my migration script..
...
def add_myModel_details(apps, schema_editor):
x = apps.get_model("myapp","myModel")
MyModel(column1 = "test", column2="2015" ).save()
.....
The slug is empty, as the save override isn't being called.
It happens because migrations don't call your save
method.
I think save method is not the best place for generate slug. Will be better to use AutoSlugField or signals.
1. signals:
In your case you may use signal pre_save.
Example:
@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
my_model = kwargs.get('instance')
if my_model.column2:
my_model.slug = slugify(my_model.column1 + " " + my_model.column2)
else:
my_model.slug = slugify(my_model.column1)
print my_model.slug
2. AutoSlugField:
It's not a standard field but a lot of libraries implement it. I use AutoSlugField from django-extensions. This field uses signals too.
Example:
slug = AutoSlugField(populate_from=("column1", "column2"))
3. save
method and migrations
But if you still want to use a save
method to generating slug I'd recommend you create data migration and add slugs manually.
Data Migrations django >= 1.7
Data Migrations south
Custom model methods are not available during migrations.
Instead, you can run put code in your RunPython
function that modifies your model instances the way the custom save()
would have.
References: