About Dependent Autocompletes

You can create one autocomplete field dependent on another one with django-autocomplete-light pretty easy using the special forwarding feature:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# shops/forms.py
from django import forms
from dal import autocomplete
from .models import Country, City

class ShopLocationForm(forms.Form):
    country = forms.ModelChoiceField(
        queryset=Country.objects.all(),
        widget=autocomplete.ModelSelect2(
            url="country-autocomplete",
        )
    )
    city = forms.ModelChoiceField(
        queryset=City.objects.all(),
        widget=autocomplete.ModelSelect2(
            url="city-autocomplete",
            forward=["country"],
        )
    )

Then you would define your views that return autocompleted values as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# shops/views.py
from dal import autocomplete
from .models import Country, City

class CountryAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = Country.objects.all()

        if self.q:
            qs = qs.filter(name__istartswith=self.q)

        return qs

class CityAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = City.objects.all()

        country = self.forwarded.get("country", None)

        if country:
            qs = qs.filter(country=country)

        if self.q:
            qs = qs.filter(name__istartswith=self.q)

        return qs

The JavaScript of django-autocomplete-light connects the fields in the frontend, and moreover, it is smart enough to work with prefixed and inline forms.

Tips and Tricks Programming Development Django 3.2 Django 2.2 django-autocomplete-light