如何在Django中创建slug?

253 投票
11 回答
148967 浏览
提问于 2025-04-15 11:27

我正在尝试在Django中创建一个SlugField

我创建了一个简单的模型:

from django.db import models

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()

然后我做了这个:

>>> from mysite.books.models import Test
>>> t=Test(q="aa a a a", s="b b b b")
>>> t.s
'b b b b'
>>> t.save()
>>> t.s
'b b b b'

我原本期待得到b-b-b-b

11 个回答

71

Thepeer的回答做个小修正:如果你想在模型类中重写save()函数,最好给它添加一些参数:

from django.utils.text import slugify

def save(self, *args, **kwargs):
    if not self.id:
        self.s = slugify(self.q)

    super(test, self).save(*args, **kwargs)

否则,像test.objects.create(q="blah blah blah")这样的代码会出现force_insert错误(因为有不期望的参数)。

113

有一些UTF-8字符会出现特殊情况

举个例子:

>>> from django.template.defaultfilters import slugify
>>> slugify(u"test ąęśćółń")
u'test-aescon' # there is no "l"

这个问题可以通过使用 Unidecode 来解决

>>> from unidecode import unidecode
>>> from django.template.defaultfilters import slugify
>>> slugify(unidecode(u"test ąęśćółń"))
u'test-aescoln'
462

你需要使用 slugify 这个函数。

>>> from django.template.defaultfilters import slugify
>>> slugify("b b b b")
u'b-b-b-b'
>>>

你可以通过重写 save 方法来自动调用 slugify

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()
    
    def save(self, *args, **kwargs):
        self.s = slugify(self.q)
        super(Test, self).save(*args, **kwargs)

要注意的是,上面的做法会导致当你编辑 q 字段时,网址会发生变化,这样可能会导致 链接失效。更好的做法可能是在创建新对象时只生成一次 slug:

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField()
    
    def save(self, *args, **kwargs):
        if not self.id:
            # Newly created object, so set slug
            self.s = slugify(self.q)

        super(Test, self).save(*args, **kwargs)

撰写回答