8

This question is very similar to one I just asked href: Can I get Google search results to use/display the final redirect url?, but now the question is specific to Django.

My site has webpage urls that use the following format:

www.mysite.com/id/pretty_title

The front page links to these pages, but the href actually contains some parameters:

 www.mysite.com/id/?some_ugly_parameters_to_let_me_know_what_search_it_is_from

This then redirects to

www.mysite.com/id/pretty_title

which shows the page.

My issue is that Google's search results show the link to the page as the ugly url instead of the pretty redirected one.

What I have learned is that I need to provide a canonical link. But how can I do this when the ugly url page never really exists, at least not as one that I have written?

What happens server side is that the view of the ugly url does a redirect:

return HttpResponseRedirect(pretty_url)
Community
  • 1
  • 1
user984003
  • 28,050
  • 64
  • 189
  • 285

3 Answers3

11

I think this is the correct built template tag that you're looking for. {{ request.build_absolute_uri }}

Alex Phelps
  • 393
  • 4
  • 8
7

You can just put it as part of the HTML returned from the Django template, in the <head> section. Do you have a base.html in your Django? You can setup a {% block %} as a placeholder for the canonical URL and then set that value in each individual page that {% extends base.html %}

base.html

<html>
<head>
  <link rel="canonical" href="{% block canonical_url %}{% endblock %}">
</head>
...
bakkal
  • 54,350
  • 12
  • 131
  • 107
  • This html page is displayed by pretty_url. Or does it also 'count' as being displayed by the ugly_url since it redirects to this? – user984003 Mar 29 '14 at 08:30
  • 1
    In your Django there should be only one view that returns that unique content, all you have to do is get the canonical tag into the HTML of that one view. Wether the content from that view is accessible through one or another URL is not important. – bakkal Mar 29 '14 at 08:37
2

A lot of these proposed solutions have issues if (1) you want your www subdomain to be the canonical one and (2) there are URL params in the request path.

I would actually propose to hard code it in the base template and append request.path.

<link rel="canonical" href="https://www.example.com{{ request.path }}">

If you do end up wanting to use build_absolute_uri, I would do it as follows in your view (or you could create a template function):

canonical_url = request.build_absolute_uri(request.path)

Calling build_absolute_uri() without an argument will call request.get_full_path() and append that to your domain. If a user finds your site via https://www.example.com/?param=123, your canonical URL will include that param.

getup8
  • 6,949
  • 1
  • 27
  • 31