我是否也应该在 Django URL 中使用 slug 字段?

Should I use slug field too in django URLs?

我正在开发一个类似博客的应用程序,其中 post 具有相似或有时相同的标题。用户还可以随时编辑 post 的标题。 目前我的网址看起来像这样。

<a href="{% url 'myapp:read' post.id %}">{{post.title}} </a>

现在我读了几个答案,其中 id 他们已经通过 slug 太像这个问题的 url 了。 即使 id url 也将是独一无二的,对吧?那为什么 slug?如果它是为了使 url 人性化,那么也应该存储它吗? 总结一下:

  1. 如果 id 是唯一的,那为什么 slug
  2. 如果它很重要,那么我们应该存储它吗?
  3. 如果它与 canonical-link 有任何关系,请详细说明 canonical links 的工作原理以及 slug 如何帮助它?或者至少让我找到来源。

参考: when to store slugfield in database in django? 而这个 answer

  1. If id is unique then why slug?

Slug 只是让您快速了解此 URL 内容的一种方式 - 仅使用 id 无法保证其可读性。

  1. If its important then should we store it?
这个问题的

URL 可能是 Should I use slug field too in django URLs?,但它仍然重定向到相同的 post。但话虽如此,这也取决于实施。在这种情况下,Stack Overflow 可能会检查与 post ID 相对应的有效 slug,如果未找到,则重定向到原始 slug。

我刚刚更改了问题的标题,结果 URL 也发生了变化:

old => http://whosebug.com/questions/42407755/should-i-use-slug-field-too-in-django
new => http://whosebug.com/questions/42407755/should-i-use-slug-field-too-in-django-urls

因此,如果您存储 slug,则需要确保每次更改标题时都会对其进行更新。

  1. If it has anything to do with canonical-link please elaborate the working of canonical links & how slug can help it?

规范 link 被搜索引擎用来识别导致相同内容的重复 URL。您可以查看此 post 的源代码,您可以在 HEAD 中找到以下规范 link:

<link rel="canonical" href="http://whosebug.com/questions/42407755/should-i-use-slug-field-too-in-django-urls">

当您搜索与此 URL 匹配的关键字时,搜索引擎将收集此 URL 并 return 给您。搜索引擎对页面进行排名的因素之一是匹配 URL 中的关键字。好的 slug 可以帮助搜索引擎 return 根据 URL.

中匹配的关键字为用户提供最佳结果

您需要通过 1 个唯一标识符来识别 post。这可以是 ID 或 slug。两者都使用是没有意义的,而且容易出错。您可以在标题中同时包含 slug 和 id,在这种情况下,您应该完全忽略 URL 中传递的 slug 并使用 ID。

您可以忽略该 slug,只使用这样的 ID:

url(r'^(?:[\w-]+)/(?<id>\d+)/$', BlogView.as_view(), name='blog-view')

如果这样做,则根本不需要存储 slug,只需在每次使用时根据标题生成它即可。

就个人而言,我更喜欢 slugs,因为它们提供更友好的 URLs,可以与 Django 很好地集成。例如,对于基于 class 的视图,您可以创建如下所示的 URL:

url(r'^(?P<slug>[\w-]+)/$', BlogView.as_view(), name='blog-view')

而且您基于 class 的视图非常干净:

class BlogView(DetailView):
    model=BlogEntry

就是这样! Django 自动知道通过 slug 查找模型并假设您的模板已正确命名,您不需要连接任何其他东西(好吧,你可能会这样做)。 github 上确实有关于此设置的 helpful gist

如果您想使用 slug,请在保存记录时生成它,并在发生冲突时使用某种自动修改使其唯一(或让用户手动覆盖它)。在我的一篇博客中,我将日期合并到 slug 中以使其更加独特,然后使用递归函数来确保它是唯一的。 (here's an little tutorial someone made on making unique slugs)。包含一些手动 over-ride 弹头的方法是个好主意。

上面link他用的是for循环,个人比较喜欢递归函数如:

def autoslug(self, slug, attempt=1):
    if MyModel.objects.filter(slug=slug).exists():
        return autoslug(slug[:47]+"%d" % attempt, attempt + 1)
    else:
        return slug

您在模型上创建了一个 slug 字段来存储 slug。例如,基于 Class 的视图可以传递一个 slug,它会神奇地弄清楚你想要什么。 Django 有多种内部工具通过该名称引用它,因此请保持简单并使用 django 期望的相同名称。

此外,给定资源的 URL 应该不变,因此 link 是持久的。更改标题时更改 slug 意味着资源的 URL 发生变化,在我看来,同一资源具有不断变化的 URL 总是一个坏主意。这对 SEO 不利,对 link 在外部使用您的资源的任何人都不利。