如何在Django中创建一个slug?

时间:2009-05-08 01:17:11

标签: python django django-models slug

我正在尝试在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

9 个答案:

答案 0 :(得分:386)

您需要使用slugify功能。

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

您可以通过覆盖slugify方法自动致电save

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字段时更改您的网址,can cause broken links。在创建新对象时,最好只生成一次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)

答案 1 :(得分:110)

有一些极端情况下有一些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'

答案 2 :(得分:62)

对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错误(意外参数)。

答案 3 :(得分:29)

如果您使用管理界面添加模型的新项目,则可以在ModelAdmin中设置admin.py并使用prepopulated_fields自动输入slug:

class ClientAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('name',)}

admin.site.register(Client, ClientAdmin)

此处,当用户在name字段的管理表单中输入值时,slug将自动填充正确的符合条件的name

答案 4 :(得分:21)

在大多数情况下,slug不应该改变,所以你真的只想在第一次保存时计算:

class Test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField(editable=False) # hide from admin

    def save(self):
        if not self.id:
            self.s = slugify(self.q)

        super(Test, self).save()

答案 5 :(得分:5)

如果您不想将slugfield设置为Not ed editable,那么我相信您需要将Null和Blank属性设置为False。否则,在尝试保存在管理员中时会出现错误。

因此对上述示例的修改将是::

class test(models.Model):
    q = models.CharField(max_length=30)
    s = models.SlugField(null=True, blank=True) # Allow blank submission in admin.

    def save(self):
        if not self.id:
            self.s = slugify(self.q)

        super(test, self).save()

答案 6 :(得分:5)

在您的管理类中使用prepopulated_fields

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}

admin.site.register(Article, ArticleAdmin)

答案 7 :(得分:3)

我正在使用Django 1.7

在模型中创建一个SlugField,如下所示:

slug = models.SlugField()

然后在admin.py中定义prepopulated_fields;

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}

答案 8 :(得分:-1)

您可以查看docs for the SlugField,以更具描述性的方式进一步了解它。