Callbacks¶
Parsing the host from
request.get_host()
and lookup
its corresponding object instance (e.g. site) in every view violates DRY.
If these dynamic hosts had a lot of views this would become particularly
unwieldy.
To remedy this, you can optionally specify a callback method to be called if your host matches.
Simply define a callback function:
from django.shortcuts import get_object_or_404
from django.contrib.auth.models import User
def custom_fn(request, username):
request.viewing_user = get_object_or_404(User, username=username)
..and pass it as the callback
paramter to the host
object:
from django.conf import settings
from django_hosts import patterns, host
host_patterns = patterns('',
host(r'www', settings.ROOT_URLCONF, name='www'),
host(r'(?P<username>\w+)', 'path.to.custom_urls',
callback='path.to.custom_fn', name='with-callback'),
)
This example avoids the duplicated work in every view by attaching a
viewing_user
instance to the request object. Views referenced by the
“dynamic” URLconf can now assume that this object exists.
The custom method is called with the request
object and any named
captured arguments, similar to regular Django url processing.
Callbacks may return either None
or an
HttpResponse
object.
- If it returns
None
, the request continues to be processed and the appropriate view is eventually called. - If a callback returns an
HttpResponse
object, thatHttpResponse
is returned to the client without any further processing.
Note
There are a few things to keep in mind when using the callbacks:
- Callbacks are executed with the URLconf set to the second argument in
the
host_patterns
list. For example, in the example above, the callback will be executed with the URLconf aspath.to.custom_urls
and not the default URLconf. - This can cause problems when reversing URLs within your callback as
they may not be “visible” to
django.core.urlresolvers.reverse()
as they are specified in (eg.) the default URLconf. - To remedy this, specify the
urlconf
parameter when callingreverse()
. - When using dynamic hosts based on user input, ensure users cannot specify names that conflict with static subdomains such as “www” or their subdomain will not be accessible.
- Don’t forget to add
handler404
andhandler500
entries for your custom URLconfs.
Included callbacks¶
django-hosts
includes the following callbacks for use with the Django
contrib app django.contrib.sites
:
-
django_hosts.callbacks.
host_site
(request, *args, **kwargs)¶ A callback function which uses the
django.contrib.sites
contrib app included in Django to match a host to aSite
instance, setting arequest.site
attribute on success.Parameters: - request – the request object passed from the middleware
- *args – the parameters as matched by the host patterns
- **kwargs – the keyed parameters as matched by the host patterns
It’s important to note that this uses
reverse_host()
behind the scenes to reverse the host with the given arguments and keyed arguments to enable a flexible configuration of what will be used to retrieve theSite
instance – in the end the callback will use adomain__iexact
lookup to get it.For example, imagine a host conf with a username parameter:
from django.conf import settings from django_hosts import patterns, host settings.PARENT_HOST = 'example.com' host_patterns = patterns('', host(r'www', settings.ROOT_URLCONF, name='www'), host(r'(?P<username>\w+)', 'path.to.custom_urls', callback='django_hosts.callbacks.host_site', name='user-sites'), )
When requesting this website with the host
jezdez.example.com
, the callback will act as if you’d do:request.site = Site.objects.get(domain__iexact='jezdez.example.com')
..since the result of calling
reverse_host()
with the username'jezdez'
is'jezdez.example.com'
.Later, in your views, you can nicely refer to the current site as
request.site
for further site-specific functionality.
-
django_hosts.callbacks.
cached_host_site
(request, *args, **kwargs)¶ A callback function similar to
host_site()
which caches the resultingSite
instance in the default cache backend for the time specfified asHOST_SITE_TIMEOUT
.Parameters: - request – the request object passed from the middleware
- *args – the parameters as matched by the host patterns
- **kwargs – the keyed parameters as matched by the host patterns