1

I would like to be able to change the slug using slugify if the slug already exist. This site will have multiple products named the same but when you call the product using get_object_or_404 you will get an error because two or more objects are being called at one time. To avoid this I need to auto increment the slugify if the slug already exist.

Can anyone help me with this?

class Product(models.Model):
    product_name = models.CharField(max_length=500, blank=True)
    product_description = models.TextField(blank=True)
    company = models.ForeignKey(Company, blank=True, null=True)
    category = models.ForeignKey(Category, blank=True, null=True)
    manufacturer = models.ForeignKey(Manufacturer)
    buy_link = models.URLField(max_length=1000, blank=True)
    product_image_url = models.URLField(max_length=1000, blank=True)
    price = models.CharField(max_length=30, blank=True)
    orginal_price = models.CharField(max_length=30, blank=True)
    stock = models.CharField(max_length=30, blank=True)
    sku = models.CharField(max_length=250, blank=True)
    slug = models.SlugField(max_length=500)
    date_added = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.product_name)
        super(Product, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('products:product_detail', args=[self.slug]) #kwargs={'slug': self.slug}

    def __str__(self):
        return self.product_name  
Tom Myers
  • 159
  • 1
  • 13

2 Answers2

1

What if you combine both product name and id, something like:

def save(self, *args, **kwargs):
    self.slug = slugify("{obj.product_name}-{obj.id}".format(obj=self))
    super(Product, self).save(*args, **kwargs)

Or, you can generate a slug, check if it exists and, if does, increment and append the counter - sample here and here.

Also, you should probably enforce the slug uniqueness:

slug = models.SlugField(max_length=500, unique=True) 
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
0

You can use django-autoslug if you don't want to roll your own. Simply install the package with pip (pip install django-autoslug), import into your model file, and add it as a field. When set up with unique=True, if django-autoslug runs into a collision, it will append a number to the end of the slug, and increment that number if it already exists.

Example from the Github page:

from django.db.models import CharField, Model
from autoslug import AutoSlugField

class Article(Model):
    title = CharField(max_length=200)
    slug = AutoSlugField(populate_from='title', unique=True)

From the docs:

# globally unique, silently fix on conflict ("foo" --> "foo-1".."foo-n")
slug = AutoSlugField(unique=True)
Darrick Herwehe
  • 3,553
  • 1
  • 21
  • 30
  • This is great except that from Django 1.9 onwards 'django.core.urlresolvers' has been deprecated. – Felix Dec 11 '18 at 23:50