Skip to main content

django-admin-dependent-autocomplete

django-admin-dependent-autocomplete adds a single capability to Django Admin's built-in autocomplete: a ForeignKey autocomplete can be constrained by another ForeignKey in the same admin form.

It deliberately reuses Django Admin's autocomplete_fields, Select2 bundle, AutocompleteJsonView, permissions, search_fields, pagination, and JSON format. It does not introduce a second autocomplete implementation or any runtime dependency besides Django.

Install

pip install django-admin-dependent-autocomplete

Add django_admin_dependent_autocomplete to INSTALLED_APPS so Django can discover its static JavaScript file.

Simple shorthand dependency

from django.contrib import admin
from django_admin_dependent_autocomplete.admin import DependentAutocompleteAdminMixin

from .models import Address, City, Country


@admin.register(Country)
class CountryAdmin(admin.ModelAdmin):
    search_fields = ["name"]


@admin.register(City)
class CityAdmin(admin.ModelAdmin):
    # Required by Django Admin's native autocomplete.
    search_fields = ["name"]


@admin.register(Address)
class AddressAdmin(DependentAutocompleteAdminMixin, admin.ModelAdmin):
    autocomplete_fields = ["city"]
    autocomplete_dependencies = {
        "city": "country",
    }

For the configuration above, Address.city is the autocomplete child and Address.country is its parent. The related City model must have a country ForeignKey to the same model. The autocomplete results are then equivalent to:

City.objects.filter(country_id=selected_country_id)

search_fields on the target model's ModelAdmin is required by Django Admin for every field listed in autocomplete_fields.

Target fields with a different name

The short form above uses country both as the parent field on Address and as the ForeignKey on City. When those names differ, configure the target model field explicitly:

autocomplete_dependencies = {
    "city": {
        "depends_on": "selected_country",
        "lookup": "country",
    },
}

Here selected_country is the field on the source admin form and country is the ForeignKey on the target autocomplete model. Both names are checked server-side; the browser only ever supplies the selected parent primary key.

The package installs a small per-admin URL that delegates to Django's native autocomplete view. It applies the configured parent filter before invoking the related model admin's get_search_results(). Permissions, search_fields, custom get_search_results(), limit choices, pagination, and the native JSON response remain in use. The browser only sends a parent value; it never sends a lookup name, and the relationship is validated server-side from the mapping.

Changing a parent clears its dependent child. Existing values on a change form are left intact until the parent changes. When the parent is empty, its dependent autocomplete returns no results.

Chained dependencies

Each mapping can use an explicit target lookup, so source form fields do not need to share names with the target model relationships. For example, a Country → District → City chain can use intentionally different source names:

class AddressAdmin(DependentAutocompleteAdminMixin, admin.ModelAdmin):
    autocomplete_fields = ["selected_district", "selected_city"]
    autocomplete_dependencies = {
        "selected_district": {
            "depends_on": "selected_country",
            "lookup": "country",
        },
        "selected_city": {
            "depends_on": "selected_district",
            "lookup": "district",
        },
    }

Here Address.selected_country, selected_district, and selected_city are the form fields, while District.country and City.district are the target model ForeignKey fields. Changing a country clears its district and city; changing a district clears its city. Saved values remain visible on change forms until the user changes an ancestor field.

Mixing with a project ModelAdmin

Put DependentAutocompleteAdminMixin before your ModelAdmin subclass:

class AddressAdmin(DependentAutocompleteAdminMixin, ProjectModelAdmin):
    autocomplete_fields = ["city"]
    autocomplete_dependencies = {"city": "country"}

The mixin uses cooperative super() for formfield_for_foreignkey(), get_urls(), and check(). A custom formfield_for_foreignkey() further down the MRO can still explicitly provide a widget; in that case it takes precedence. Existing get_form() implementations are unaffected.

Current limits

Version 0.1 supports one ForeignKey parent and one ForeignKey autocomplete child per mapping entry. It does not support many-to-many fields, non-admin forms, generic foreign keys, arbitrary callbacks, or multiple parents for one child. Multiple entries can form chained dependencies. Inline formsets receive the JavaScript behavior when added, but they are not a separately expanded API surface yet.

Compared with django-autocomplete-light

django-autocomplete-light is a full-featured autocomplete framework. This package intentionally does much less: it extends Django Admin's built-in autocomplete with dependent field filtering.

Compatibility

The package requires Python 3.8+ and supports Django 3.2, 4.2, 5.0, 5.1, and 5.2. CI covers those Django release lines, including Python 3.8 with Django 3.2. Django is the only runtime dependency.

Run the included test app

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
python testapp/manage.py migrate
python testapp/manage.py createsuperuser
python testapp/manage.py seed_data
python testapp/manage.py runserver

Open /admin/testapp/address/add/. Select Paraguay, then a district (Capital or Central), then a city. Select Argentina to see its districts and cities. Changing the country clears both dependent fields; changing a district clears its city. Reopen a saved address to verify the selected district and city stay visible.

Development checks

pytest
ruff check .
python -m build
twine check dist/*

To run the oldest supported environment locally, install the development dependencies with Python 3.8 and Django 3.2, then run pytest again.

Roadmap

Possible future additions include multiple parent dependencies, more relation types, and a documented inline-specific API, without changing the simple mapping used in v0.1.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_admin_dependent_autocomplete-0.1.0.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file django_admin_dependent_autocomplete-0.1.0.tar.gz.

File metadata

File hashes

Hashes for django_admin_dependent_autocomplete-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e07676a4428365cbe5943cc5a1c9d10e803d05e9376f25dc2e95b6ab2b326fea
MD5 8fbd14cad3068f28cc9018b02be4343c
BLAKE2b-256 3aeb2d64bd9410f993102c8eae660c731021499f391cc337a3eefd866a13cab7

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_admin_dependent_autocomplete-0.1.0.tar.gz:

Publisher: release.yml on JuanBer90/django-admin-dependent-autocomplete

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_admin_dependent_autocomplete-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_admin_dependent_autocomplete-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0952f2df52f3c0068c7e285d176eb7969a9ae28502370392a16c8ccbd360d589
MD5 57e9708854d5a803ddd8f0c01166be9b
BLAKE2b-256 8c172d5cbb6d300fa93add4806410ee094ba6733649f0efe0a095a74a1940ecb

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_admin_dependent_autocomplete-0.1.0-py3-none-any.whl:

Publisher: release.yml on JuanBer90/django-admin-dependent-autocomplete

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page