Integrating with django-hosts

Django-hosts routes requests for specific hosts to different URL schemes defined in modules called “hostconfs”. Django-geoip plays nice with django-hosts, allowing to redirect user to specific geodomain.

In this example will redirect to for users from the East and for american ones. For european users in will remain` without redirect (default location).

  1. Install and setup django-geoip Let’s assume we have defined this custom location model:

    # app/
    from django_geoip.models import Country, GeoLocationFacade
    class Location(GeoLocationFacade):
        slug = models.SlugField('Site kwarg')
        country = model.ForeignKey(Country)

    This model is referenced in

    GEOIP_LOCATION_MODEL = 'app.models.Location'

    We also need to change default user location storage mechanism, because it’s fully determined by hostname:

  2. Install and setup django-hosts

    pip install django-hosts==0.4.2

    Make sure you also followed other steps: adding to INSTALLED_APPS, adding a middleware, creating, setting up ROOT_HOSTCONF and DEFAULT_HOST.


    django_geoip.middleware.LocationMiddleware should come before django_hosts.middleware.HostsMiddleware in MIDDLEWARE_CLASSES to make things work together.

  1. Configure host_patterns in

    host_patterns = patterns('',
        # Default pattern that redirects users to <location>
        # depending on their IP address
        host(r'www', settings.ROOT_URLCONF, name='www', callback=detect_location),
        # Geodomain for specific region: <location>, doesn't redirect
        host(r'(?P<site_slug>[\w-]+)', settings.ROOT_URLCONF, name='location', callback=save_location),
  2. Define detect_location callback:

    from django_geoip.base import location_model, Locator
    from django_hosts.reverse import reverse_host
    def detect_location(request):
        """ Callback takes request object and redirects to specific location domain if appropriate """
        default_location = location_model.get_default_location()
        # User is a first-timer and doesn't have a cookie with detected location
        if Locator(request).is_store_empty():
            # If we're at www-address, but not from default location, then do redirect.
            if request.location != default_location:
                return _redirect(request, domain=reverse_host('location', kwargs={'site_slug': request.location.slug}))
        request.location = default_location
  1. Define save_location callback:

    def save_location(request, site_slug):
        """ Store location in request, overriding geoip detection """
        request.location = get_object_or_404(Location, slug=site_slug)