15

I want to get absolute url in templates. I can't do with url. It gives me a relative URL. I need to get this:

http://domain.tld/article/post

but Django gives me just

/article/post

I played with settings.py but it didn't work. (debug=false, allowed hosts vs.)

Template code:

{% url 'blog:detail' blog.slug %}
Kevin Brown-Silva
  • 40,873
  • 40
  • 203
  • 237
neuraminidase7
  • 486
  • 2
  • 7
  • 19
  • possible duplicate of [django full url in get\_absolute\_url](http://stackoverflow.com/questions/3994060/django-full-url-in-get-absolute-url) – karthikr Jul 25 '13 at 18:46
  • https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.build_absolute_uri This might help you. – sawan gupta Jul 25 '13 at 18:48

2 Answers2

31

This is easy to do in a view. For example:

from django.core.urlresolvers import reverse

def Home(request): 
    posts = Article.objects.filter(published=True).order_by('-publish') 
    site = Site.objects.get_current()

    c = RequestContext(request, { 
        'posts': [{'post': post,
                   'url': request.build_absolute_uri(reverse('blog:detail', args=[post.slug]))}
                  for post in posts]
        'site': site,
    }) 

    return render_to_response('templates/index.html', c)

Then, in your template, while you're looping with {% for postobj in posts %} you can access postobj.post and postobj.url.

If you want to do this in the template instead you can probably create your own template tag without too much trouble.

Kevin Christopher Henry
  • 46,175
  • 7
  • 116
  • 102
  • Where to place it? I added the views and models to question. Can you help me please? I'm working it for 2 days :S And I'm using it in for loop. – neuraminidase7 Jul 26 '13 at 08:23
  • OK, I edited the answer with a code example based on your views.py. Some other notes: `filter()` doesn't raise a `DoesNotExist` exception, it just returns an empty list; but `get()` _does_ raise a `DoesNotExist` exception so you should check for it in your `Detail` view. – Kevin Christopher Henry Jul 27 '13 at 20:35
7

After a long time meeting with Django, I learned a lot of things. For this issue, I created an absolute URL templatetag.

Add this to your template tags, then use like default url tag:

{% absurl 'some-view' with, arguments %}

Here is the Gist for the absolute URL templatetag, you will need to add request object to template_context_processors, otherwise this will not work. To achieve this, open your settings.py and add these following lines:

from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.request',
)
neuraminidase7
  • 486
  • 2
  • 7
  • 19
  • You may also need to load the template tag, e.g. assuming the file is named `absurl.py` then you'd add `{% load absurl %}` to the top of your template – Aleck Landgraf Sep 29 '15 at 22:33
  • Neat solution, thanks. Remember to restart django dev server to load the newly added templatetag. – Thales Ceolin Sep 29 '16 at 18:49