Django重击网址 - 如何处理碰撞?

时间:2009-09-29 04:23:55

标签: python django url slug collision

我目前正在Django开展一个玩具项目。

我的部分应用允许用户留下评论。我想获取评论的标题并将其强化以创建一个网址。

因此,如果用户写了一篇名为“有史以来最好的东西!”的评论,那么网址就像:www.example.com/reviews/the-best-thing-ever

这一切都很好,但处理两个用户选择相同标题的情况的最佳方法是什么?我不想让标题必须是唯一的。

我已经考虑过在某个网址添加评论ID,但我想避免任何不会发生碰撞的网址的额外信息。

有什么想法吗?

4 个答案:

答案 0 :(得分:6)

我会推荐类似AutoSlugField的内容。它有一些关于配置唯一性的选项(uniqueunique_with),并且还有一个额外的好处,即如果您愿意,可以根据模型上的其他字段自动生成slug。

答案 1 :(得分:6)

我从不喜欢独特的slug字段/方法的一件事是,如果你对一个标题有很多冲突,你最终会运行几个查询来尝试确定一个可用的slug。我知道你提到你不想显示非冲突slu的id,但是,就性能而言,我认为这是更好的选择。为了使URL更好看,我更喜欢在slug之前嵌入id,以便URL采用www.example.com/reviews/1/the-best-thing-ever的形式。

答案 2 :(得分:2)

from django.template.defaultfilters import slugify

def slugify_unique(value, model, slugfield="slug"):
        suffix = 0
        potential = base = slugify(value)
        while True:
            if suffix:
                potential = "-".join([base, str(suffix)])
            if not model.objects.filter(**{slugfield: potential}).count():
                return potential
            suffix += 1      
"""
above function is not my code, but i don't remember exactly where it comes from
you can find many snippets with such solutions searching for 'unique slug' and so
"""


class ReviewForm(forms.ModelForm):

    def save(self, user, commit=True):    
        self.instance.slug = slugify_unique(self.cleaned_data['title'], self.Meta.model)                       
        review = super(ReviewForm, self).save(commit)
        review.save()
        return review

    class Meta:
        model = Review

当然会更改相应的名称和表单定义,但您明白了这一点:)

答案 3 :(得分:0)

我会(在表单验证中)只是检查是否使用了slug,然后添加一些东西,或者是一个数字“my-cool-idea_2”或实际的id