规范链接和301重定向如果URL与别名不匹配

8 投票
2 回答
4947 浏览
提问于 2025-04-16 10:33

我正在尝试在Django/Python中实现一个类似于Stack Overflow的URL方案。

比如说,URL中会包含一个主键(pk)和标题的简短描述(slug),对于这个问题(ID #4787731),它的URL是

https://stackoverflow.com/questions/4787731/canonical-links-and-301-redirect-if-url-doesnt-match-slug

如果我以后更改标题(或者随便在URL中放一些乱七八糟的东西),网站仍然能通过ID知道我想要哪个问题,并会自动重定向到正确的URL,比如说尝试一下。

https://stackoverflow.com/questions/4787731/canonical-links-MODIFIED-URL

所以

  • 在我的页面中,包含规范链接的最佳方法是什么,例如

    <link rel="canonical" href="https://stackoverflow.com/questions/4787731/canonical-links-and-301-redirect-if-url-doesnt-match-slug">

(我可以使用get_absolute_url吗)

  • 识别当前URL与规范链接不匹配并发出301重定向的最佳方法是什么?

注意 - 这个问题类似,但只涉及动态生成slug或静态存储slug的情况。

2 个回答

1

我按照Yuji的有用指导进行了操作,但发现你需要使用 HttpResponsePermanentRedirect 这个对象,才能得到一个永久的301重定向,而不是临时的302重定向。

6

1: 我觉得如果已经有301重定向的话,使用规范标签就没什么意义了。

我们来想象一个场景,你把网址从 /q/111/hello-world 改成了 /q/111/foobar。搜索引擎不会认为这两个网址是一样的,除非它们访问了原来的网址,并且这个网址上有指向 /q/111/foobar 的规范标签(但它不会去访问,因为现在是301重定向,这样就切断了这两个页面之间的任何关联)。

2: 我会选择直接的方法。定义一个不唯一的 slug 字段,然后在你的详细视图中与捕获的URL进行比较。

# models
class MyModel(models.Model):
    # ...
    non_unique_slug = models.SlugField()

    def get_absolute_url(self):
        return "/questions/%s/%s" % (self.id, self.non_unique_slug)


# urls
    r'^questions/(?P<id>\d+)/(?P<slug>[\w-]+)/$' 

# views
def my_view(request, id, slug):
    page = Page.objects.get(id=id)
    if not slug == page.slug:
        return http.HttpResponsePermanentRedirect(page.get_absolute_url())

    # render page
    return direct_to_template(request, "foobar.html", {'page': page})

撰写回答