django-smart-selects

raw JSON →
1.7.2 verified Fri May 01 auth: no python

A Django application to handle chained model fields, allowing dropdowns to be dynamically filtered based on parent selections. Current version 1.7.2 (2024). Release cadence: irregular, with minor patches.

pip install django-smart-selects
error Unresolved reference 'ChainedForeignKey'
cause Importing from wrong module (e.g., smart_selects.fields instead of smart_selects.db_fields).
fix
Use: from smart_selects.db_fields import ChainedForeignKey
error 'NoneType' object has no attribute '_meta'
cause The chained_field argument points to a field that does not exist on the parent model, or the model hasn't been migrated.
fix
Check that the chained_field name matches exactly a field on the foreign-key target model. Run makemigrations and migrate.
error django.core.exceptions.ImproperlyConfigured: 'smart_selects' is not a valid application
cause Missing 'smart_selects' in INSTALLED_APPS.
fix
Add 'smart_selects' to INSTALLED_APPS in settings.py.
error ChainedSelect is not updating when parent changes
cause JavaScript not loaded or conflicts with other JS (e.g., jQuery version).
fix
Ensure django-smart-selects static files are served. Check browser console for JS errors. If using jQuery 3+, it's supported since 1.5.3.
gotcha ChainedForeignKey does not work correctly with 'limit_choices_to' - the chain filtering overrides it. Use raw_id_fields instead if you need custom filtering.
fix Avoid using limit_choices_to on chained fields.
deprecated Setting SMART_SELECTS_USE_SELECCT2 in Django settings is deprecated as of 1.6.0; it is now always True.
fix Remove the setting from settings.py.
breaking Versions before 1.5.3 used a different import path ('smart_selects.fields') which is removed in current versions.
fix Change imports to 'smart_selects.db_fields'.
gotcha When using in formsets, the chained field may not update correctly because the JavaScript relies on element IDs. Ensure each form in the formset has a unique prefix.
fix Use formset management form and ensure prefix is set.

Basic usage: define a ChainedForeignKey in models and register in admin.

# models.py
from django.db import models
from smart_selects.db_fields import ChainedForeignKey

class Location(models.Model):
    continent = models.CharField(max_length=100)

class Country(models.Model):
    continent = models.ForeignKey(Location, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)

class City(models.Model):
    country = ChainedForeignKey(
        Country,
        chained_field="continent",
        chained_model_field="continent",
        show_all=False,
        auto_choose=True,
        sort=True
    )
    name = models.CharField(max_length=100)

# admin.py
from django.contrib import admin
from .models import City

admin.site.register(City)