Yura Raagin
Yura Raagin

Reputation: 1

Django: Generate slug before save model

When i save the model from admin interface a first time i need to autogenerate the slug. I use slugify and pre_save signal and my slug field have unique=True option. But when i push save button the object slugfield raise validation error (Required field) because field is unique, i think. I thought that pre_save goes before validation. Or i am wrong?

# models.py

class Slugified(models.Model):
    slug = models.CharField(unique=True, max_length=50)

    class Meta:
        abstract = True

class Post(Slugified):
    title = models.Charfield(max_length=50)

@receiver(pre_save, sender=Post)
def save_slug(sender, instance, *args, **kwargs):
    instance.slug = slugify(instance.title)

Upvotes: 0

Views: 2736

Answers (1)

knbk
knbk

Reputation: 53729

The form automatically generated by the admin sees the slug field as a required field. The pre_save signal receiver works correctly, but the code never tries to save the model as the form doesn't validate.

The solution to this is to all blank values:

class Slugified(models.Model):
    slug = models.CharField(unique=True, max_length=50, blank=True)

This way, the field is not required in the form and the slug gets set before the instance is saved.

Also, please note that your code does not correctly handle duplicate slugs. If two post titles generate identical slugs, an IntegrityError would be raised. This is easier solved in the save method than in the pre_save signal receiver:

class Slugified(models.Model):
    slug = models.CharField(unique=True, max_length=50, blank=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        while True:
            try:
                return super(Slugified, self).save(*args, **kwargs)
            except IntegrityError:
                # generate a new slug

Upvotes: 4

Related Questions