45

Djangomodels.SlugField()可以帮助我们创建一些看起来很酷的 url。我的问题是为什么将其指定为字段

假设我有这个模型

 class Blog(models.Model):
    title = models.CharField()

如果我想添加 slug,我可以使用

 class Blog(models.Model):
    title = models.CharField()

    def title_slug(self):
       return slugify(self.title)

网址中我可以使用

(r'^blog/(?P<id>\d+)/(?P<slug>[-\w]+)/$', 'app.views.blog_view'),

并在视图中

def blog_view(request, id ,slug):
    get_object_or_404(Blog, pk=id)
    ...

网址看起来像

example.com/blog/23/why-iam-here/

有三件事让我采用这种方法

  1. Slug 字段不具有隐含的唯一性。
  2. get_object_or_404(Blog, pk=id)必须比 快get_object_or_404(Blog, slug=slug)
  3. 向现有模型添加 slug 字段涉及数据迁移。

那么为什么是 SlugField()?,除了动态生成 slug 的成本外,上述方法的缺点是什么?

4

3 回答 3

40

为什么在 Django 中使用 SlugField()?因为:

  1. 它对人类友好(例如 /blog/ 而不是 /1/)。
  2. 在标题、标题和 URL 中创建一致性是很好的 SEO。

动态生成的 slug 的最大缺点是接受 urls.py 中的 slug 而不是使用 slug 来获取正确的对象?这是糟糕的设计。

如果您提供和接受 slug,但不检查它们,那么您有多个 URL 返回相同的内容。所以/1/useful-slug//1/this-is-a-bs-slug/都将返回相同的页面。

这很糟糕,因为它不会让人类的生活变得轻松。您的访问者必须提供一个 id 和一些多余的东西。重复的页面是搜索引擎的噩梦。哪一页是正确的?重复的页面最终排名较低。请参阅https://support.google.com/webmasters/answer/40349?hl=en(最后一页)

您可以争辩说您始终如一地实现自己生成的精美链接,但人们和机器人一直在猜测 URL(请参阅您的日志文件)。当您接受所有蛞蝓时,人类和机器人总是会猜对。

将 slug 保存到 db 也可以节省处理能力。您一次生成 slug 并重复使用它。每次查找蛞蝓或生成蛞蝓会更(低)效吗?

管理员中的 Slug 字段对于让编辑者有机会编辑 slug 很有用。也许是为了提供标题中没有但仍然值得一提的额外信息。

奖励:要更新迁移的数据:

from django.template.defaultfilters import slugify

for obj in Blog.objects.filter(slug=""):
    obj.slug = slugify(obj.title)
    obj.save()
于 2013-07-05T23:17:18.183 回答
12

Slug 字段不具有隐含的唯一性。

a 没有隐含的唯一性CharField。您需要指定unique=True是否要确保每一行在数据库级别是唯一的。您必须同时使用 aCharField和 a来执行此操作,SlugField因此两者都没有优势

get_object_or_404(Blog, pk=id) 必须比 get_object_or_404(Blog, slug=slug) 快。

由于主键上的索引可能会有非常小的差异,但它可能可以忽略不计。CharField这与使用vs无关SlugField——您刚刚创建了一个不同的 URL,它接受id并使用它来进行查找。

向现有模型添加 slug 字段涉及数据迁移。

将 a 添加CharField到现有模型也需要数据迁移,因此这里没有优势。


SlugFields只是CharField需要额外的验证。看代码。你打破了 Django 的 DRY 黄金法则——不要重复自己。

此外,如果您只使用 aCharField您不会在表单级别获得任何验证,因此您可以非常轻松地创建一个不符合 slugs 验证的“slug”,即它可能包含不允许的空格或字符在一个网址中。

同样使用这种方法,如果您更改标题,则您的 URL 已更改,现在您所有的旧链接都已失效。有一个 slug 字段可以防止这种情况。

您在这里给自己制造了更多麻烦 - 只需使用SlugField

于 2013-07-05T21:49:20.550 回答
0

我正在制作一个多租户日历应用程序。如果日历 url 类似于:/calendar/id/,其中 id 是连续的整数,那么黑客可能会猜测 id 并找到比我想要的更多的关于我的业务的信息。通过使用 url /calendar/slug/ 找到所有日历要困难得多。

于 2020-09-01T16:21:25.827 回答