Canonical links and 301 redirects if the URL does not match slug

I am trying to implement a URL scheme similar to stack overflow in django / python.

eg. pk is stored in the url along with the header pool, so for this question (id # 4787731) the url

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

If later I change the title (or just add some random crud to the url), the site will still know what question I will be (by ID), and redirect 301 to the correct URL. try it.

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

So,

  • What is the best way to include canonical links to my pages, for example

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

(can i use get_absolute_url)

  • What is the best way to find out if the current URL does not match the canonical link and returns 301?

Note. This question is similar, but only allows the creation of a bullet on the fly or statically.

+8
redirect python django slug
source share
2 answers

1: I don’t think it makes sense to use a canonical tag if there are 301 anyway.

Imagine a scenario in which you change the URL from /q/111/hello-world to /q/111/foobar . Engines do not assume that they are equal unless they visit the original url with a canonical tag on it pointing to /q/111/foobar (which is usually because it is now 301, tearing off any evidence of a link between pages).

2: I would do it straightforwardly. Define a non-unique slug field and compare with the captured URL in your verbose view.

 # 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}) 
+6
source share

I followed Yuji's helpful instructions, but found that you need to use the HttpResponsePermanentRedirect object to get a constant 301 instead of a temporary 302.

+1
source share

All Articles