8

我正在尝试在 django/python 中实现类似于堆栈溢出的 URL 方案。

例如,pk 与标题的 slug 一起存储在 URL 中,因此对于这个问题(id #4787731),URL 是

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

如果我稍后更改标题(或者只是在 url 中添加一些随机的杂物),那么该站点仍然会知道我在追随哪个问题(通过 ID),并将 301 重定向到正确的 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 的情况。

4

2 回答 2

6

1:如果反正有 301,我认为使用规范标签没有意​​义。

/q/111/hello-world让我们想象一下将 URL 从更改为 的场景/q/111/foobar。引擎不会假设这两者是相等的,除非他们访问原始 url,其上的规范标签指向/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})
于 2011-01-25T01:01:31.643 回答
1

我按照 Yuji 的有用说明进行操作,但发现您需要使用该HttpResponsePermanentRedirect对象来获得永久 301 而不是临时 302。

于 2012-01-19T06:22:11.867 回答