How it works¶
Overview¶
django-completion has three separate pieces:
- Cache builder — runs inside Django and writes project metadata to JSON
- Internal completion helper — reads the cache and decides which candidates match the current command line
- Shell scripts — collect shell words, call the helper, and hand candidates to bash or zsh
Tab completion never imports Django and never touches the database.
The cache¶
Location: {project_root}/.django-completion-cache.json
The cache is generated runtime state. It contains:
schema_version- management command names
- app labels and their origin (
localorpip) - option flags per command
- option and command help text
- migration names discovered on disk
- non-fatal migration-discovery warnings
- a
generated_attimestamp
The cache is a plain JSON file. You can inspect it with any JSON viewer. It is machine-specific runtime state and should not be committed.
Migration discovery¶
Migration completion is based on migration files on disk, not database state.
For each installed app, django-completion respects settings.MIGRATION_MODULES:
- custom module path — inspect that module
None— treat the app as having no migrations- missing key — use the default
{app}.migrationspackage
Only public .py migration files are included. __init__.py, private files, hidden files, non-Python files, and __pycache__ are ignored. zero is added by the completion helper at tab-completion time, not stored in the cache.
Cache refresh lifecycle¶
The cache is built or rebuilt in three situations:
autocomplete install— always builds immediately after installing the hookautocomplete refresh— always rebuilds on demand- Auto-refresh — after each
manage.pycommand, a background thread checks whether the cache is older than 60 seconds and rebuilds if so
Auto-refresh uses a process-local lock so only one rebuild runs at a time. It never blocks the command that triggered it.
Set DJANGO_COMPLETION_AUTO_REFRESH = False to disable the background thread. Manual autocomplete refresh still works.
The AppConfig hook¶
When django_completion is in INSTALLED_APPS, its AppConfig wraps Django's management command execution so the cache can refresh after commands run. The shell completion scripts do not import Django; they only read the cache file.
The wrapper is idempotent. It checks for a sentinel attribute before applying so command execution is not wrapped repeatedly.
Installed shell scripts¶
autocomplete install writes managed completion scripts to:
Each generated script starts with a version marker:
autocomplete status compares that marker with the installed package version and reports whether the script is current or outdated.
Shell RC block¶
The install command adds a marker-delimited source block to ~/.bashrc or ~/.zshrc:
# django-completion begin
source ~/.local/share/django-completion/completion.bash
# django-completion end
At tab-press time, the shell script:
- walks up from
$PWDto find the nearest.django-completion-cache.json - serializes shell words and the current-word index
- calls
python3 -m django_completion._complete - passes returned candidates to shell-native completion primitives
If the cache is missing or unreadable, the script returns no completions silently. Use autocomplete status --verbose for diagnostics.
Internal helper¶
The internal helper lives at django_completion._complete. It is intentionally not a public API.
The helper accepts a cache path, shell words, current-word index, and output format. It implements the command-aware rules for bash and zsh, including migrate app-label and migration-name completion.
Uninstall cleanup¶
autocomplete uninstall:
- strips the marker-delimited source block from shell RC files
- deletes the managed script files
- removes
~/.local/share/django-completion/if it is empty
It never touches files outside the managed path.