During production i've had the need to various urls, and i've found a few ways to do this, i leave this here so hopefully somebody can use it, and as a self reminder.
1. Using the Sites app to get the current domain url
def current_domain_url():
"""Returns fully qualified URL (no trailing slash) for the
current site."""
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
protocol = getattr(settings, 'MY_SITE_PROTOCOL', 'http')
port = getattr(settings, 'MY_SITE_PORT', '')
url = '%s://%s' % (protocol, current_site.domain)
if port:
url += ':%s' % port
return url
Good side:
It does'nt need the request to work, only the Sites app with your list of sites.
Bad side:
The problem with this approach is that if it depends on the sites app, this is good enough if you are diciplined enough to keep that app updated with your development enviroment, your stating server and your production server, it can be annoying.
Via
Fragments of code
2. Using the HTTP_REFERER to get the current url
def current_site_url(request):
"""Returns fully qualified URL (no trailing slash) for the
current site."""
return '/'.join(request.meta['HTTP_REFERER'].split('/')[:3])
Good side:
I'm not sure where this function could be used, maybe as a helper to prevent sites from outside yours to load some urls. Because of the:
Bad side:
It only works if the current view was called from another url. If the user types directly the url of the current view, it won't work because there is not http referer. Use it only if you are sure your view will always be called from a hyperlink.
Plus the client can modify the http header to send a different referer so it cannot be relied.
3. Using the request HTTP_HOST get the current url
def current_site_url(request):
full_path = ('http', ('', 's')[request.is_secure()],
'://', request.META['HTTP_HOST'], request.path)
return ''.join(full_path)
Good side:
It's the simplest form to get your current url. All it takes is a request.
Bad side:
Same problem as the HTTP_REFERER the client can modify the http header so it can't be relied upon.
Credit goes to limodou, the author of
this django snippet
4. Using the built in build_absolute_uri to get the current url
from django.core.urlresolvers import reverse
def current_site_url(request,*args,**kwargs):
"""Returns fully qualified URL (no trailing slash) for the
current site."""
relative_url = reverse(*args,**kwargs)
return request.build_absolute_uri(relative_url)
Good side:
It's pretty solid, it only takes the current view, or an url name, basically everything reverse() accepts this functions does.
Bad side:
This function needs a relative url you want to get the full url, so its uses is limited. Also, the build_absolute_uri was introduce in Django 1.2+ so that could be a
problem for older apps. And i'm not really sure about its short comings
i haven't .