Django AJAX Selects for Admin AutoComplete

3.0.3 · active · verified Fri Apr 17

django-ajax-selects is a Django app that enhances the Django Admin interface by providing jQuery UI AutoComplete functionality for ForeignKey, ManyToManyField, and CharField lookups. It helps users quickly find and select related objects or text entries in large datasets, improving usability for forms with many options. The current version is 3.0.3, supporting Django 3.2 to 5 and Python 3.10+. Releases are made as needed, typically in response to Django version updates or critical bug fixes.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to integrate `django-ajax-selects` into your Django project's admin interface. It includes defining a simple model, creating a `LookupChannel` for an Author model, configuring `settings.py` (by adding `ajax_select` to `INSTALLED_APPS`), configuring `urls.py` (by including `ajax_select.urls`), and finally using `make_ajax_form` with `AjaxSelectAdmin` to enable autocomplete for the ForeignKey field (`author`) in the Django admin. The `settings.configure()` block is for standalone demonstration purposes; in a real project, you would modify your existing configuration files.

import os
import django
from django.conf import settings
from django.urls import path, include
from django.db import models
from django.contrib import admin

# NOTE: In a real Django project, you would typically integrate these pieces
# into your existing settings.py, urls.py, models.py, lookup_channels.py, and admin.py files.
# The settings.configure() block below is for making this example self-contained and runnable.

# Minimal Django setup for a self-contained example
# In your project, these settings would be in your project's settings.py
settings.configure(
    DEBUG=True,
    SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'insecure-secret-key-for-development-only'),
    ROOT_URLCONF='__main__',
    INSTALLED_APPS=[
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'ajax_select' # <-- Crucial: Add ajax_select to your INSTALLED_APPS
    ],
    TEMPLATES=[
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ],
    STATIC_URL='/static/',
    STATIC_ROOT=os.path.join(os.getcwd(), 'staticfiles'), # Required for collectstatic
    # Optional: Configure AJAX_SELECT_BOOTSTRAP = True for Bootstrap theme if using it
)
django.setup()

# 1. Define simple models (in your app's models.py)
class Author(models.Model):
    name = models.CharField(max_length=200)
    birth_year = models.IntegerField(null=True, blank=True)

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
    published_year = models.IntegerField(null=True, blank=True)

    def __str__(self):
        return self.title

# 2. Create a lookup channel (in your app's lookup_channels.py or similar module)
from ajax_select import LookupChannel, register

@register('authors') # <-- 'authors' is the channel name you'll reference
class AuthorLookup(LookupChannel):
    model = Author
    search_field = 'name' # Field to search in the model

    def get_query(self, q, request):
        # Customize your query here
        return self.model.objects.filter(name__icontains=q).order_by('name')

    def format_item_display(self, obj):
        # Customize how results are displayed in the dropdown
        return f"{obj.name} ({obj.birth_year or 'N/A'})"

# 3. Register your models with the Admin and apply ajax_select (in your app's admin.py)
from ajax_select.admin import AjaxSelectAdmin
from ajax_select import make_ajax_form

@admin.register(Book)
class BookAdmin(AjaxSelectAdmin):
    # Use make_ajax_form to integrate the lookup channel with a ForeignKey
    form = make_ajax_form(Book, {'author': 'authors'}) # 'author' is the FK field, 'authors' is the lookup channel name

admin.site.register(Author)
# No need to register Book if using the @admin.register decorator

# 4. Define URL patterns (in your project's urls.py)
urlpatterns = [
    path('admin/', admin.site.urls),
    path('ajax_select/', include('ajax_select.urls')), # <-- Crucial: Include ajax_select URLs
]

# Example of how you would typically run this in a Django project:
# 1. python manage.py makemigrations myapp
# 2. python manage.py migrate
# 3. python manage.py createsuperuser (to access admin)
# 4. python manage.py runserver
# Then navigate to /admin/ and add a Book to see the autocomplete in action.

view raw JSON →