4

I have code to create slug automatic use slugify. but when I edit title slug is not generate with new title.

this is code model.py

class Tag(models.Model):

title           = models.CharField(max_length=50)
slug            = models.CharField(max_length=200, null=True, blank=True)
description     = models.TextField()
created_date    = models.DateTimeField(auto_now_add=True)
published_date  = models.DateTimeField(blank=True, null=True)

def publish(self):
    self.published_date = timezone.now()
    self.save()

def save(self):
    if not self.slug:
        self.slug = slugify(self.title)
    return super(Tag, self).save()

def __str__(self):
    return self.title

can you help solve this problem?

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
User0511
  • 665
  • 3
  • 11
  • 27

2 Answers2

7

In your current code, you slugify only when the slug does not exist previously. This condition will arise only when you are saving the first time, or when the title is absent, or the slug is empty.

Instead, you need to save it everytime the slug is changed (which in turn depends on the title).

So, Alter your save method to:

def save(self, *args, **kwargs):
    self.slug = slugify(self.title)
    return super(Tag, self).save(*args, **kwargs))

Update notes: After some testing, it turns out it is better to simply pass along the args and kwargs because you have no way of knowing which params you need to handle. Based on this answer.

Blairg23
  • 11,334
  • 6
  • 72
  • 72
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • thanks its work, but when i create in the first time slug is not auto generate. how? – User0511 Mar 27 '15 at 04:16
  • @apsi No changing 'and' with 'or' wouldn't work, that will leave you with the same problem as you currently have. I have edited the condition, check that. Also, don't forget to *accept and upvote* :) – Anshul Goyal Mar 27 '15 at 04:27
  • i try changing 'and' with 'or' not error and your new conditions its works. thanks – User0511 Mar 27 '15 at 04:37
1

Easiest way i've learned by myself: - In your Django app models you have to do the next

from django.template.defaultfilters import slugify

class MyClass(models.Model):
  title = models.CharField(max_length=40, null=False)
  slug = models.SlugField(default=slugify(title), unique=True)

  def save(self, *args, **kwargs):
    self.slug = slugify(self.title)
    super(MyClass, self).save(*args, **kwargs)

And that's all, by default your slug row will contain the last string detected in the title, so you have to make the title not null to make this thing work right. Hope I helped you.

manicho
  • 11
  • 3