我如何在Django中创建一个鼻涕虫?

我试图在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

141443 次浏览

你需要使用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字段被编辑时,上面的内容将导致您的URL发生变化,而会导致链接断裂. xml字段将被编辑。当你创建一个新对象时,最好只生成一次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)

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

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


admin.site.register(Client, ClientAdmin)

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

在大多数情况下,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()

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

如果您不想将slugfield设置为不可编辑,那么我相信您将希望将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()

在你的管理类中使用prepopulated_fields:

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


admin.site.register(Article, ArticleAdmin)

有一些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'

我使用的是Django 1.7

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

slug = models.SlugField()

然后在admin.py中定义prepopulated_fields;

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

你可以查看SlugField . docs,以更描述性的方式了解它。