我正在尝试在django / python中实现类似于堆栈溢出的URL方案。
E.g。 pk与标题的slug一起存储在URL中,因此对于这个问题(id#4787731),URL是
https://stackoverflow.com/questions/4787731/canonical-links-and-301-redirect-if-url-doesnt-match-slug
如果我稍后更改了标题(或者只是将一些随机的crud放入网址中),那么该网站仍然会知道我追究的是哪个问题(通过ID)并且301会重定向到正确的网址 - 例如尝试。
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)
注意 - 此问题类似,但仅针对generating the slug on the fly or statically.
的情况答案 0 :(得分:6)
1:如果反正有301,我认为使用规范标签是没有意义的。
让我们假设您将网址从/q/111/hello-world
更改为/q/111/foobar
。引擎不会假设两者是相同的,除非他们访问原始URL,其上的标准标记指向/q/111/foobar
(它不会,因为它现在是301,切断页面之间关系的任何证据)
2:我会直截了当地做到这一点。定义一个非唯一的slug
字段,并在详细信息视图中与捕获的网址进行比较。
# 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})
答案 1 :(得分:1)
我遵循了Yuji的有用说明,但发现您需要使用HttpResponsePermanentRedirect
对象来获取永久301而不是临时302.