Django Unique Slug by id

Viewed 5170
class Product(models.Model):
    title = models.CharField(max_length=75)

class Deal(models.Model):
    product = models.ForeignKey(Product)
    slug = models.SlugField(max_length=255, unique=True)

Having a similar basic setup as above, I want to generate unique slugs for each Deal instance using product title of it's deal and id of the deal itself. IE: "apple-iphone-4s-161" where 161 is the id of the deal and the text before is the title of the product.

For this, how can I overwrite the save() method of the Deal model to apply it?

4 Answers

You should not have your id in that slug field at all. The two main reasons for this are:

  1. It creates the problem you are having
  2. It's redundant data in the database – the id is already stored

But there is a simple solution to your problem: The only reason why the slug is stored in the database is so you can find a row by slug. But you don't need that – you have the ID. So you should do this:

class DealManager(models.Manager):
    def get_by_slug(slug):
       return self.get(id=slug.rsplit('-', 1)[1])


class Deal(models.Model):
    product = models.ForeignKey(Product)

    objects = DealManager()

    @property
    def slug(self):
        return slugify(f'{self.name}-f{self.id}')

In your view or wherever you need to retrieve an item given a slug, you can just do Deal.objects.get_by_slug(slug).

Related