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
HttpResponseobject, thatHttpResponseis 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_patternslist. For example, in the example above, the callback will be executed with the URLconf aspath.to.custom_urlsand 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
urlconfparameter 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
handler404andhandler500entries 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.sitescontrib app included in Django to match a host to aSiteinstance, setting arequest.siteattribute 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 theSiteinstance – in the end the callback will use adomain__iexactlookup 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.sitefor further site-specific functionality.
-
django_hosts.callbacks.cached_host_site(request, *args, **kwargs)¶ A callback function similar to
host_site()which caches the resultingSiteinstance 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