Django: Unique Slug for Urls
June 21, 2019 | Coding | No Comments

Let’s imagine a situation where you want to create, lets say, a blog post or a news article in Django. You want to use take the Title and turn it into a slug that can be used in the URL. Meaning, it needs to be unique, or at least, unique for the date. Depending on the URL parameters you with you use.
You could make it a editable field with a unique property, but its probably better to abstract it away and check recursively for existing matches and increment a number on the end. Simplifying the process.
First, lets define the model as such.
class Article(models.Model): title = models.CharField(max_length=255) slug = models.SlugField(unique=True, blank=True) body = models.TextField() published = models.BooleanField(default=True) published_on = models.DateTimeField(blank=True) updated_on = models.DateTimeField(blank=True) author = models.ForeignKey(User, on_delete=models.CASCADE)
Next we will need to override the models save method.
def save(self, *args, **kwargs): self.updated_on = timezone.now() if not self.id: self.published_on = timezone.now() # find unique slug cnt = 0 while not self.slug: if cnt > 0: # Create a new slug string with the counter slug = "{}-{}".format(slugify(self.title), cnt) else: slug = slugify(self.title) # check to see if a article exists with that slug a = Article.objects.filter(slug=slug) if not a: # Assign the slug, this will end the loop. self.slug = slug else: cnt += 1 super(Article, self).save(*args, **kwargs)
You could easily abstract that loop out into a function.
Django, Python