Skip to main content

Dead simple autocompletion for Django admin list_filter with goodies.

Project description

Version Python Django Ruff PyPI version PyPI - Downloads Codecov Django Packages

Django Admin List Filter

Dead simple autocompletion for Django admin list_filter. This was made using the libraries shipped with Django (select2, jquery), Django’s built-in list filters and Django’s built-in AutocompleteJsonView.

This package is an improved version of the previously created django-admin-autocomplete-list-filter package. It supports Django version 5 and above. Please note that the django-admin-autocomplete-list-filter package is now deprecated. Since I am no longer part of the organization where it was initially developed, I cannot archive it.

No extra package or install required!

Before Django Admin List Filter

Before Django Admin List Filter

After Django Admin List Filter

After Django Admin List Filter


Installation

pip install dalf

Add dalf to your INSTALLED_APPS in your settings.py:

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "dalf", # <- add
]

Usage

Use DALFModelAdmin, inherited from admin.ModelAdmin to inject media urls only. You have some filters;

  • DALFRelatedField: inherited from admin.RelatedFieldListFilter.
  • DALFRelatedFieldAjax: inherited from admin.RelatedFieldListFilter
  • DALFRelatedFieldAjaxMulti: inherited from admin.FieldListFilter - multi-select with AJAX
  • DALFRelatedOnlyField: inherited from admin.RelatedOnlyFieldListFilter.
  • DALFChoicesField: inherited from admin.ChoicesFieldListFilter.

Example models.py

# models.py
import uuid

from django.conf import settings
from django.db import models


class Category(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=255)

    def __str__(self):
        return self.title


class Tag(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class Post(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    category = models.ForeignKey(to='Category', on_delete=models.CASCADE, related_name='posts')
    author = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='posts')
    title = models.CharField(max_length=255)
    body = models.TextField()
    tags = models.ManyToManyField(to='Tag', blank=True)

    def __str__(self):
        return self.title

Example admin.py:

# admin.py
from dalf.admin import DALFModelAdmin, DALFRelatedOnlyField, DALFRelatedFieldAjax, DALFRelatedFieldAjaxMulti
from django.contrib import admin
from YOURAPP.models import Post

@admin.register(Post)
class PostAdmin(DALFModelAdmin):
    list_filter = (
        ('author', DALFRelatedOnlyField),       # if author has a post!
        ('category', DALFRelatedFieldAjax),     # enable ajax completion for category field (FK)
        ('tags', DALFRelatedFieldAjax),         # enable ajax completion for tags field (M2M) - single select
        ('tags', DALFRelatedFieldAjaxMulti),    # enable ajax completion for tags field (M2M) - multi select
    )

Multi-select filter in action:

DALFRelatedFieldAjaxMulti

That's all... There is also DALFChoicesField, you can test it out:

# admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User

from dalf.admin import (
    DALFModelAdmin,
    DALFChoicesField,
    DALFRelatedOnlyField,
    DALFRelatedFieldAjax,
)

from YOURAPP.models import Post, Category, Tag

# must be registered, must have search_fields, required for `author` field demo.
# this is demo purpose only, you can register/import your own/custom User model
class UserAdmin(BaseUserAdmin):
    search_fields = ['username']
    ordering = ['username']

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

@admin.register(Post)
class PostAdmin(DALFModelAdmin):
    list_filter = (
        ('author', DALFChoicesField),        # enable autocomplete w/o ajax (FK)
        ('category', DALFRelatedFieldAjax),  # enable ajax completion for category field (FK)
        ('tags', DALFRelatedOnlyField),      # enable ajax completion for tags field (M2M) if posts has any tag!
    )

# must be registered, must have search_fields
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    search_fields = ['title',]
    ordering = ['title']


# must be registered, must have search_fields
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    search_fields = ['name',]
    ordering = ['name']

Extras

I mostly use django-timezone-field, here is an illustration of timezone completion w/o ajax:

pip install django-timezone-field

Now add timezone field to Post model:

# modify models.py, add new ones
# ...

from timezone_field import TimeZoneField                 # <- add this line

class Post(models.Model):
    # all the other fiels
    timezone = TimeZoneField(default=settings.TIME_ZONE) # <- add this line
    
    # rest of the code

Now, just add timezone as regular list_filter:

# modify admin.py, add new ones

@admin.register(Post)
class PostAdmin(DALFModelAdmin):
    # previous codes
    list_filter = (
        # previous filters
        ('timezone', DALFChoicesField), # <- add this line
    )

That’s it!


Contributor(s)


Contribute

All PR’s are welcome!

  1. fork (https://github.com/vigo/django-admin-list-filter/fork)
  2. Create your branch (git checkout -b my-feature)
  3. commit yours (git commit -am 'add some functionality')
  4. push your branch (git push origin my-feature)
  5. Than create a new Pull Request!

I am not very proficient in JavaScript. Therefore, any support, suggestions, and feedback are welcome to help improve the project. Feel free to open pull requests!


Development

Clone the repo somewhere, and install with:

pip install -r requirements-dev.txt
pip install -e /path/to/dalf
pre-commit install

And play with the filters :)

Publish

Note to my self:

pip install build twine
rake -T

rake build           # Build package
rake bump[revision]  # Bump version: major,minor,patch
rake clean           # Remove/Delete build..
rake test            # Run tests
rake upload:main     # Upload package to main distro (release)
rake upload:test     # Upload package to test distro

Change Log

2026-01-25

  • Add DALFRelatedFieldAjaxMulti - multi-select filter with AJAX support for selecting multiple values
  • Fix clear button
  • Fix max-width (now all filters are same width)
  • Fix facet counts

2026-01-24

2025-10-06

2025-03-14

2024-11-07

2024-09-06

  • Fix dark-mode text color.

2024-08-25

  • Fix extend media in DALFModelAdmin without overriding default assets - Bahattin

2024-08-16

  • Add gettextSafe function to handle missing gettext in Django - Bahattin

2024-07-14

  • Fix choice.display last element issue

2024-07-03

Now package is working fine :) Thanks to Bahattin! Thanks to my dear friend Bahattin Çiniç’s warning, He realized that the necessary HTML, CSS, and JavaScript files were missing from the published package! I quickly fixed this and published a new version. The 0.1.0 version is a faulty version. I apologize to the users for this confusion.


You can read the whole story here.


License

This project is licensed under MIT


This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

Project details


Download files

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

Source Distribution

dalf-0.7.2.tar.gz (14.4 kB view details)

Uploaded Source

Built Distribution

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

dalf-0.7.2-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file dalf-0.7.2.tar.gz.

File metadata

  • Download URL: dalf-0.7.2.tar.gz
  • Upload date:
  • Size: 14.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for dalf-0.7.2.tar.gz
Algorithm Hash digest
SHA256 c42a9ce4d4380f4e92862f6ca5d19e075afb1a822f12e74472b47b5287e8a72f
MD5 32aaf8e5426ff010b2283fbbd63250c5
BLAKE2b-256 7230a7c49451b990c17ef5cddf42bc9aee97dcd7224fd47cd147c1dead5f3674

See more details on using hashes here.

File details

Details for the file dalf-0.7.2-py3-none-any.whl.

File metadata

  • Download URL: dalf-0.7.2-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for dalf-0.7.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a7ecfbe55ae7c8dc10ecd513c9854160aa4a9cda0456ffad33c89b2728cb67a6
MD5 bbde04f1c71d558d6ac7c8da7e5d8caa
BLAKE2b-256 478e4967f85c75539f3a87b2a82888d917b3f260d704851e8c22c70c79ea3f4c

See more details on using hashes here.

Supported by

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