Django slugify url - 如何处理冲突?

Posted

技术标签:

【中文标题】Django slugify url - 如何处理冲突?【英文标题】:Django slugified urls - how to handle collisions? 【发布时间】:2010-12-02 05:04:19 【问题描述】:

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

我的部分应用允许用户发表评论。我想取评论的标题并对其进行 slugify 以创建一个 url。

因此,如果用户写了一条名为“有史以来最好的东西!”的评论,则 URL 将类似于:www.example.com/reviews/the-best-thing-ever

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

我曾考虑在某处的 url 中添加评论 ID,但我想避免为任何不冲突的 url 提供额外信息。

有什么想法吗?

【问题讨论】:

【参考方案1】:

我会(在表单验证中)检查是否使用了 slug,然后向其中添加一些内容,数字“my-cool-idea_2”或实际 id

【讨论】:

【参考方案2】:

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

【讨论】:

这是我正在考虑的解决方案,虽然在这种情况下,slug 原来是毫无意义的养眼。它虽然很快,但可以让您完全摆脱这个问题。在一个“真正的”应用程序中,我可能会采用这条路线,但我仍然对如何处理这个问题以及仍然允许非冲突 url 完全没有任何 id 感兴趣。 我还应该注意,如果您抬头看一下 url 栏,这似乎与 SO 使用的方法相同:) 好吧,看来我的公司很好。至于消除所有的身份,另外两个答案绝对是要走的路。当我最初开始 slug 时,我使用了我在某处找到的一种独特的 slug 方法(它与 Zalew 发布的几乎相同)。 我不会说它毫无意义的养眼,它仍然为 SEO 服务。 我知道我发表任何评论都为时已晚,但仍然想指出这一点:在 url 中使用 id 并依赖它们来获得唯一性可能会让您陷入一些 SEO 危险,因为以下 url将包含完全相同的内容:example.com/reviews/1/some-cool-thing example.com/reviews/1/other-cool-thing example.com/reviews/1/it-is-still-cool 一些机器人以自行探测不同的网址而闻名,他们会“找到”这些网址并搞砸您的 SEO 工作【参考方案3】:

我会推荐像AutoSlugField 这样的东西。它提供了一些关于配置唯一性的选项(uniqueunique_with),并且如果您愿意,还可以根据模型上的另一个字段自动生成 slug。

【讨论】:

【参考方案4】:
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

当然要更改适当的名称和表单定义,但你明白了 :)

【讨论】:

以上是关于Django slugify url - 如何处理冲突?的主要内容,如果未能解决你的问题,请参考以下文章

django-rest-framework 如何处理多个 URL 参数?

如何处理 django-rest-framework 中 url 模式中的外键关系

Django Fixtures 如何处理 ManyToManyFields?

如何处理 Django 中未应用的迁移?

如何处理 Django 中不共享同一个域的前端

如何处理 django 查询集中的变量字符串?