Django Dealing with foreign keys referencing large tables


Example

By default, Django renders ForeignKey fields as a <select> input. This can cause pages to be load really slowly if you have thousands or tens of thousand entries in the referenced table. And even if you have only hundreds of entries, it is quite uncomfortable to look for a particular entry among all.

A very handy external module for this is django-autocomplete-light (DAL). This enables to use autocomplete fields instead of <select> fields.

django-autocomplete-light example

views.py

from dal import autocomplete

class CityAutocomp(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = City.objects.all()
        if self.q:
            qs = qs.filter(name__istartswith=self.q)
        return qs

urls.py

urlpatterns = [
    url(r'^city-autocomp/$', CityAutocomp.as_view(), name='city-autocomp'),
]

forms.py

from dal import autocomplete

class PlaceForm(forms.ModelForm):
    city = forms.ModelChoiceField(
        queryset=City.objects.all(),
        widget=autocomplete.ModelSelect2(url='city-autocomp')
    )

    class Meta:
        model = Place
        fields = ['__all__']

admin.py

@admin.register(Place)
class PlaceAdmin(admin.ModelAdmin):
    form = PlaceForm