Full URL in Django

The application I’m developing includes an XML feed, in which one of the items is a URL Unfortunately, using the {% url %} tag in the template only gives the path portion of the URL. Time for a little research.

Many web posts pointed me to the Sites framework included with Django, as it can return the domain for the site. I tried it out, and it worked, but I didn’t like how it would have to be implemented in my multiple server scenario (laptop, DEV server, QA server, Production). Each would have to have any entry in the sites table, and the SITE_ID in the settings.py file for each instance would have to point to the correct entry. This would be awkward at best, and would limit the possibility of making the application reusable.

A couple of bloggers mentioned using RequestSite instead. It shares the same API with the Sites class, but doesn’t use the sites table. Instead, the domain name is pulled from the request object. Here’s a sample of the view logic:

   from django.contrib.sites.models import RequestSite    
    site_name = RequestSite(request).domain
    
    return render_to_response('template.xml', 
                              {'entries': queryset, 'site_name' : site_name}, 
                              context_instance=RequestContext(request), 
                              mimetype='text/xml')

After pulling the domain from the request, it is passed along to the template in the context dictionary. In the template, I can reference the variable ‘site_name‘ in front of the {% url %} tag. However, before I have a full URL, I also need to know the protocol.

Another blog post demonstrated the is_secure attribute of the request object. Testing this attribute can help us determine is the protocol is http or https. The temple code for a full URL is:

{% if request.is_secure %}https{% else %}http{% endif %}://{{ site_name }}
{% url entry e.pk %}

Maybe a little clumsy, but it gets the job done without hard coding anything.

I’d love to hear your thoughts in the comments.

Comments are closed.