240

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

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

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

4

9 回答 9

446

您将需要使用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请注意,在编辑字段时,上述内容会导致您的 URL 发生变化,从而导致链接断开。当您创建一个新对象时,最好只生成一次 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)
于 2009-05-08T01:22:34.240 回答
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'
于 2012-08-31T09:05:21.163 回答
68

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

于 2009-09-26T04:36:35.140 回答
31

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

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

admin.site.register(Client, ClientAdmin)

在这里,当用户在管理表单中为该name字段输入一个值时,slug将自动填充正确的 slugified name

于 2009-05-09T07:26:29.480 回答
22

在大多数情况下,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()
于 2009-05-09T10:10:12.487 回答
6

如果您不想将 slugfield 设置为不可编辑,那么我相信您需要将 Null 和 Blank 属性设置为 False。否则,当您尝试在 Admin 中保存时会出现错误。

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

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()
于 2010-12-14T15:26:49.690 回答
6

prepopulated_fields在您的管理类中使用:

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

admin.site.register(Article, ArticleAdmin)
于 2011-02-04T08:14:47.780 回答
4

我正在使用 Django 1.7

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

slug = models.SlugField()

然后在admin.py定义prepopulated_fields;

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}
于 2015-02-15T13:58:37.550 回答
0

您可以查看文档,SlugField以便以更具描述性的方式了解更多信息。

于 2018-08-14T07:05:12.247 回答