2013-03-04 44 views
2

在Django的早期階段,可以在模型中預先填充SlugField。最佳實踐:在Django中預先填充SlugField(不包含管理模塊)

在管理模塊我會用

prepopulated_fields = {'slug':('title',),} 

我發現,處理它Unique Slugify一個片段,但我懷疑,這是最好的方式。

那麼最好的做法是自動生成一個SlugField而不使用管理模塊?

我喜歡使用ModelForm來對頭文件中的表單進行置換,它應該自動生成一個唯一的URL。

回答

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() 

UPDATE:爲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' 

FWIW:我剛剛更新了我的模型,消除了get_nickname方法,並添加一個簡單的lambdasave方法的頂部:

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 
... 
+0

謝謝!我還發現了另一個功能豐富的獨特slu app應用程序[django-autoslug](https://bitbucket.org/neithere/django-autoslug) – 2013-03-04 13:51:31

+0

毫無疑問,有一些嚴重的第三方應用程序在那裏!我進行了輕量級的導入'slugify'並添加了'if slug_test'以確保唯一性。我的所有動機都有點愚蠢,所以感謝您的放縱 – Cole 2013-03-04 14:01:16

+0

您的答案絕對是輕量級的,在大多數情況下更好的解決方案 - 感謝您的更新。但爲什麼你要檢查元音和長度?你是否儘量保持網址儘可能短? – 2013-03-04 14:12:27