{"id":9661,"library":"django-ajax-selects","title":"Django AJAX Selects for Admin AutoComplete","description":"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.","status":"active","version":"3.0.3","language":"en","source_language":"en","source_url":"https://github.com/crucialfelix/django-ajax-selects","tags":["django","admin","autocomplete","ajax","forms","jquery","ui"],"install":[{"cmd":"pip install django-ajax-selects","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"This is a Django application and requires a compatible Django version (3.2 to 5.x for v3.x+).","package":"Django","optional":false}],"imports":[{"symbol":"LookupChannel","correct":"from ajax_select import LookupChannel"},{"symbol":"register","correct":"from ajax_select import register"},{"symbol":"make_ajax_form","correct":"from ajax_select import make_ajax_form"},{"symbol":"AjaxSelectAdmin","correct":"from ajax_select.admin import AjaxSelectAdmin"},{"symbol":"AutoCompleteSelect","correct":"from ajax_select import AutoCompleteSelect"},{"symbol":"AutoCompleteSelectMultiple","correct":"from ajax_select import AutoCompleteSelectMultiple"}],"quickstart":{"code":"import os\nimport django\nfrom django.conf import settings\nfrom django.urls import path, include\nfrom django.db import models\nfrom django.contrib import admin\n\n# NOTE: In a real Django project, you would typically integrate these pieces\n# into your existing settings.py, urls.py, models.py, lookup_channels.py, and admin.py files.\n# The settings.configure() block below is for making this example self-contained and runnable.\n\n# Minimal Django setup for a self-contained example\n# In your project, these settings would be in your project's settings.py\nsettings.configure(\n    DEBUG=True,\n    SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'insecure-secret-key-for-development-only'),\n    ROOT_URLCONF='__main__',\n    INSTALLED_APPS=[\n        'django.contrib.admin',\n        'django.contrib.auth',\n        'django.contrib.contenttypes',\n        'django.contrib.sessions',\n        'django.contrib.messages',\n        'django.contrib.staticfiles',\n        'ajax_select' # <-- Crucial: Add ajax_select to your INSTALLED_APPS\n    ],\n    TEMPLATES=[\n        {\n            'BACKEND': 'django.template.backends.django.DjangoTemplates',\n            'APP_DIRS': True,\n            'OPTIONS': {\n                'context_processors': [\n                    'django.template.context_processors.debug',\n                    'django.template.context_processors.request',\n                    'django.contrib.auth.context_processors.auth',\n                    'django.contrib.messages.context_processors.messages',\n                ],\n            },\n        },\n    ],\n    STATIC_URL='/static/',\n    STATIC_ROOT=os.path.join(os.getcwd(), 'staticfiles'), # Required for collectstatic\n    # Optional: Configure AJAX_SELECT_BOOTSTRAP = True for Bootstrap theme if using it\n)\ndjango.setup()\n\n# 1. Define simple models (in your app's models.py)\nclass Author(models.Model):\n    name = models.CharField(max_length=200)\n    birth_year = models.IntegerField(null=True, blank=True)\n\n    def __str__(self):\n        return self.name\n\nclass Book(models.Model):\n    title = models.CharField(max_length=200)\n    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')\n    published_year = models.IntegerField(null=True, blank=True)\n\n    def __str__(self):\n        return self.title\n\n# 2. Create a lookup channel (in your app's lookup_channels.py or similar module)\nfrom ajax_select import LookupChannel, register\n\n@register('authors') # <-- 'authors' is the channel name you'll reference\nclass AuthorLookup(LookupChannel):\n    model = Author\n    search_field = 'name' # Field to search in the model\n\n    def get_query(self, q, request):\n        # Customize your query here\n        return self.model.objects.filter(name__icontains=q).order_by('name')\n\n    def format_item_display(self, obj):\n        # Customize how results are displayed in the dropdown\n        return f\"{obj.name} ({obj.birth_year or 'N/A'})\"\n\n# 3. Register your models with the Admin and apply ajax_select (in your app's admin.py)\nfrom ajax_select.admin import AjaxSelectAdmin\nfrom ajax_select import make_ajax_form\n\n@admin.register(Book)\nclass BookAdmin(AjaxSelectAdmin):\n    # Use make_ajax_form to integrate the lookup channel with a ForeignKey\n    form = make_ajax_form(Book, {'author': 'authors'}) # 'author' is the FK field, 'authors' is the lookup channel name\n\nadmin.site.register(Author)\n# No need to register Book if using the @admin.register decorator\n\n# 4. Define URL patterns (in your project's urls.py)\nurlpatterns = [\n    path('admin/', admin.site.urls),\n    path('ajax_select/', include('ajax_select.urls')), # <-- Crucial: Include ajax_select URLs\n]\n\n# Example of how you would typically run this in a Django project:\n# 1. python manage.py makemigrations myapp\n# 2. python manage.py migrate\n# 3. python manage.py createsuperuser (to access admin)\n# 4. python manage.py runserver\n# Then navigate to /admin/ and add a Book to see the autocomplete in action.","lang":"python","description":"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."},"warnings":[{"fix":"Upgrade Python to 3.10+ and Django to 3.2+ before upgrading `django-ajax-selects` to version 3.x. Review your project's `requirements.txt`.","message":"Version 3.0.0 introduced significant changes, dropping support for older Python and Django versions. It now requires Python >= 3.10 and Django >= 3.2. If upgrading from 2.x, ensure your environment meets these new requirements.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Remove any custom jQuery/jQuery UI includes that conflict with the versions bundled by `django-ajax-selects`. If you need different versions, you can override the defaults in your settings. See documentation for `AJAX_SELECT_JQUERY_URL` and `AJAX_SELECT_JQUERY_UI_URL`.","message":"With version 3.0.0, jQuery and jQuery UI assets are now bundled and served directly by `django-ajax-selects`. If you were previously managing these assets yourself or using a custom CDN, you might encounter conflicts or redundant asset loading.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Upgrade your project's Python to 3.6+ and Django to 2.2+ before attempting to upgrade `django-ajax-selects` to 2.x.","message":"Version 2.0.0 dropped support for Python < 3.6 and Django < 2.2. Projects on these older versions must upgrade their Django/Python stack first.","severity":"breaking","affected_versions":">=2.0.0 <3.0.0"},{"fix":"Add `'ajax_select'` to `INSTALLED_APPS` in `settings.py` and include `ajax_select.urls` in your project's `urls.py`.","message":"You must include 'ajax_select' in your Django project's `INSTALLED_APPS` and `path('ajax_select/', include('ajax_select.urls'))` in your root `urls.py`. Failing to do so will lead to `ModuleNotFoundError` or `NoReverseMatch` errors.","severity":"gotcha","affected_versions":"All"},{"fix":"Double-check the string name passed to `LookupChannel` matches the name used in your `@register()` decorator or `settings.AJAX_LOOKUP_CHANNELS`.","message":"When using `AutoCompleteSelect` or `AutoCompleteSelectMultiple` in custom forms, ensure the `LookupChannel` argument correctly references a registered lookup channel name (e.g., `AutoCompleteSelect(LookupChannel='my_channel')`). Mismatched names will result in lookups not working.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Add `'ajax_select'` to your `INSTALLED_APPS` list in `settings.py`.","cause":"The 'ajax_select' application is not included in Django's `INSTALLED_APPS`.","error":"ModuleNotFoundError: No module named 'ajax_select'"},{"fix":"Add `path('ajax_select/', include('ajax_select.urls'))` to your project's `urlpatterns` in `urls.py`.","cause":"The URL patterns for `django-ajax-selects` are not included in your project's `urls.py`.","error":"django.urls.exceptions.NoReverseMatch: 'ajax_lookup' is not a registered namespace"},{"fix":"Ensure `django-ajax-selects` is installed and `INSTALLED_APPS` and `urls.py` are configured correctly. If on an older version, upgrade to 3.0.3+. Check if other apps or your base templates are loading conflicting jQuery/jQuery UI versions. For versions 3.0.0+, `django-ajax-selects` bundles its own JS/CSS; remove redundant includes.","cause":"This often indicates a JavaScript conflict or that jQuery/jQuery UI is not properly loaded, or loaded in a way that conflicts with `django-ajax-selects`. The 'django' object issue was specifically fixed in v3.0.3, but similar problems can arise from other JS conflicts.","error":"TypeError: Cannot read properties of undefined (reading 'jQuery') or Cannot read properties of undefined (reading 'django')"},{"fix":"Verify that your `LookupChannel` class is decorated with `@register('my_channel_name')` and that 'my_channel_name' exactly matches the string used in your form or admin configuration.","cause":"The lookup channel name specified (e.g., in `make_ajax_form`, `AutoCompleteSelect`, or `AutoCompleteSelectMultiple`) either does not exist or has not been properly registered with `@register('my_channel_name')` or configured in `settings.AJAX_LOOKUP_CHANNELS`.","error":"django.core.exceptions.ImproperlyConfigured: 'my_channel_name' is not a valid lookup channel."}]}