最佳实践:在Django中预填充SlugField(不使用管理模块)
在Django的早期版本中,可以在模型里预先填充一个SlugField。
在管理模块中,我会使用
prepopulated_fields = {'slug':('title',),}
我找到了一段代码,可以处理这个问题,链接在这里:Unique Slugify,不过我觉得这可能不是最好的方法。
那么,怎样才能在不使用管理模块的情况下,自动生成一个SlugField呢?
我想用一个ModelForm,把这个表单集成到前端页面中,这样就可以自动生成一个唯一的slug,用于URL。
1 个回答
2
这段内容是我从一个旧的模型中复制过来的(那个模型的代码写得不太好)。我想让你们看到这个思路,稍微调整一下就能用。
from django.template.defaultfilters import slugify
def get_nickname(self):
nick = self.name
vowels = ('a','e','i','o','u')
first_letter = nick[:1]
nick = nick[1:]
for vowel in vowels: nick = nick.replace(vowel,'')
nick = first_letter + nick
if len(nick) > 8:
nick = nick[:7]
return nick
def save(self, force_insert=False, force_update=False, using=None):
if not self.nickname:
self.nickname = self.get_nickname() if len(self.name)>8 else self.name
self.slug = slugify(self.nickname)
slug_test = SomeModel.objects.filter(slug=self.slug, id=self.id) # corrected to use a generic model name
if slug_test:
count = slug_test.count
self.slug = "{}{}".format(self.slug[:len(self.slug)-1], count)
super(SomeModel, self).save()
更新:对get_nick方法进行了更紧凑的代码优化……
>>> name = 'alabama'
>>> vowels = {'a', 'e', 'i', 'o', 'u'}
>>> nick = name[0] + ''.join(l for l in name[1:] if l not in vowels)
>>> nick
'albm'
顺便说一下:我刚刚更新了我的模型,去掉了get_nickname
方法,改为在save
方法的开头加了一个简单的lambda
。
vowels = {'a','e','i','o','u'}
create_nick = lambda name: name[0] + ''.join(l for l in name[1:] if l not in vowels)[:7]
if not self.nickname:
self.nickname = create_nick(self.name) if len(self.name)>8 else self.name
...