Dependencies between autocompletes

This means that the selected value in an autocomplete widget is used to filter choices from another autocomplete widget.

This page drives through the example in test_project/dependant_autocomplete/.


Consider such a model:

from django.db import models

class Dummy(models.Model):
    parent = models.ForeignKey('self', null=True, blank=True)
    country = models.ForeignKey('')
    region = models.ForeignKey('cities_light.region')

    def __unicode__(self):
        return u'%s %s' % (, self.region)

And we want two autocompletes in the form, and make the “region” autocomplete to be filtered using the value of the “country” autocomplete.


Register an Autocomplete for Region that is able to use ‘country_id’ GET parameter to filter choices:

import autocomplete_light

from cities_light.models import Country, Region

autocomplete_light.register(Country, search_fields=('name', 'name_ascii',),
    autocomplete_js_attributes={'placeholder': 'country name ..'})

class AutocompleteRegion(autocomplete_light.AutocompleteModelBase):
    autocomplete_js_attributes={'placeholder': 'region name ..'}

    def choices_for_request(self):
        q = self.request.GET.get('q', '')
        country_id = self.request.GET.get('country_id', None)

        choices = self.choices.all()
        if q:
            choices = choices.filter(name_ascii__icontains=q)
        if country_id:
            choices = choices.filter(country_id=country_id)

        return self.order_choices(choices)[0:self.limit_choices]

autocomplete_light.register(Region, AutocompleteRegion)


Actually, a normal modelform is sufficient. But it was decided to use Form.Media to load the extra javascript:

from django import forms

import autocomplete_light

from models import Dummy

class DummyForm(forms.ModelForm):
    class Media:
        We're currently using Media here, but that forced to move the
        javascript from the footer to the extrahead block ...

        So that example might change when this situation annoys someone a lot.
        js = ('dependant_autocomplete.js',)

    class Meta:
        model = Dummy
        widgets = autocomplete_light.get_widgets_dict(Dummy)

That’s the piece of javascript that ties the two autocompletes:

$(document).ready(function() {
    $('body').on('change', '.autocomplete-light-widget select[name$=country]', function() {
        var countrySelectElement = $(this);
        var regionSelectElement = $('#' + $(this).attr('id').replace('country', 'region'));
        var regionWidgetElement = regionSelectElement.parents('.autocomplete-light-widget');

        // When the country select changes
        value = $(this).val();

        if (value) {
            // If value is contains something, add it to
            regionWidgetElement.yourlabsWidget() = {
                'country_id': value[0],
        } else {
            // If value is empty, empty
            regionWidgetElement.yourlabsWidget() = {}

        // example debug statements, that does not replace using breakbpoints and a proper debugger but can hel
        // console.log($(this), 'changed to', value);
        // console.log(regionWidgetElement, 'data is', regionWidgetElement.yourlabsWidget()


Again, there are many ways to acheive this. It’s just a working example you can test in the demo, you may copy it and adapt it to your needs.