{"id":5903,"library":"django-autocomplete-light","title":"Django Autocomplete Light","description":"Django Autocomplete Light (DAL) provides a modern, fresh set of widgets for Django forms and admin, enabling easy integration of autocompletion functionality for fields like foreign keys, many-to-many, and tags. It's currently at version 3.12.1 and typically releases updates in line with Django's development or new feature requirements.","status":"active","version":"3.12.1","language":"en","source_language":"en","source_url":"https://github.com/yourlabs/django-autocomplete-light","tags":["Django","autocomplete","forms","admin","select2"],"install":[{"cmd":"pip install django-autocomplete-light","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core framework dependency, requires Django >=2.2.","package":"Django","optional":false},{"reason":"Used for JSON field handling, requires jsonfield >=2.0.2,<3.0.0.","package":"jsonfield","optional":false},{"reason":"Python 2/3 compatibility layer, requires six >=1.12.0.","package":"six","optional":false}],"imports":[{"note":"The `shortcuts` module was part of the 2.x API and is deprecated/removed in 3.x. The main `autocomplete_light` import is now for registering autocomplete classes.","wrong":"from autocomplete_light import shortcuts as al","symbol":"autocomplete_light","correct":"import autocomplete_light"},{"note":"Used to specify a Select2-powered autocomplete widget in a Django form.","symbol":"Select2QuerySetView (widget)","correct":"from dal_select2.widgets import Select2QuerySetView"},{"note":"Used to create the backend view that serves the autocomplete data.","symbol":"Select2QuerySetView (view)","correct":"from dal_select2.views import Select2QuerySetView"}],"quickstart":{"code":"import os\nimport django\nfrom django.conf import settings\nfrom django.db import models\nfrom django import forms\nfrom django.urls import path, reverse_lazy\n\nsettings.configure(\n    DEBUG=True,\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        'dal',\n        'dal_select2',\n        'testapp' # Your app name\n    ],\n    MIDDLEWARE=[\n        'django.middleware.security.SecurityMiddleware',\n        'django.contrib.sessions.middleware.SessionMiddleware',\n        'django.middleware.common.CommonMiddleware',\n        'django.middleware.csrf.CsrfViewMiddleware',\n        'django.contrib.auth.middleware.AuthenticationMiddleware',\n        'django.contrib.messages.middleware.MessageMiddleware',\n        'django.middleware.clickjacking.XFrameOptionsMiddleware',\n    ],\n    TEMPLATES=[\n        {\n            'BACKEND': 'django.template.backends.django.DjangoTemplates',\n            'DIRS': [],\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    DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},\n    STATIC_URL='/static/',\n    SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-testing-only'),\n    ROOT_URLCONF=__name__,\n)\n\ndjango.setup()\n\n# --- Your app's models.py ---\nclass Country(models.Model):\n    name = models.CharField(max_length=100, unique=True)\n\n    def __str__(self):\n        return self.name\n\n    class Meta:\n        app_label = 'testapp'\n\n\nclass City(models.Model):\n    name = models.CharField(max_length=100)\n    country = models.ForeignKey(Country, on_delete=models.CASCADE, related_name='cities')\n\n    def __str__(self):\n        return f\"{self.name} ({self.country.name})\"\n\n    class Meta:\n        app_label = 'testapp'\n\n\n# --- Your app's forms.py ---\nimport autocomplete_light\nfrom dal_select2.widgets import Select2QuerySetView\n\n\nclass CityForm(forms.ModelForm):\n    class Meta:\n        model = City\n        fields = ('name', 'country')\n        widgets = {\n            'country': Select2QuerySetView(\n                url=reverse_lazy('country-autocomplete'),\n                attrs={\n                    'data-placeholder': 'Search for a country',\n                    'data-minimum-input-length': 2,\n                }\n            )\n        }\n\n# --- Your app's views.py and urls.py combined for quickstart ---\nfrom dal_select2.views import Select2QuerySetView\n\nclass CountryAutocomplete(Select2QuerySetView):\n    def get_queryset(self):\n        # Don't forget to filter out results if a query is provided\n        qs = Country.objects.all()\n        if self.q:\n            qs = qs.filter(name__icontains=self.q)\n        return qs\n\n# --- ROOT_URLCONF definitions ---\nurlpatterns = [\n    path('country-autocomplete/', CountryAutocomplete.as_view(), name='country-autocomplete'),\n    # Example: If you were to integrate this form into a view\n    # path('city/add/', lambda request: HttpResponse(CityForm().as_p()), name='add-city'),\n]\n\n# Example usage (requires setting up Django's test client or a view)\nif __name__ == '__main__':\n    # This part would typically be in a Django shell or a real view.\n    # For demonstration, we'll just show the form rendering.\n    from django.core.management import call_command\n    from django.db import connection\n    with connection.cursor() as cursor:\n        cursor.execute(\"CREATE TABLE testapp_country (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(100) UNIQUE)\")\n        cursor.execute(\"CREATE TABLE testapp_city (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(100), country_id INTEGER REFERENCES testapp_country(id) ON DELETE CASCADE)\")\n        cursor.execute(\"INSERT INTO testapp_country (name) VALUES ('France')\")\n        cursor.execute(\"INSERT INTO testapp_country (name) VALUES ('Germany')\")\n        cursor.execute(\"INSERT INTO testapp_country (name) VALUES ('Spain')\")\n    \n    # Print the form HTML to demonstrate the widget integration\n    print(\"\\n--- Example City Form HTML ---\\n\")\n    print(CityForm().as_p())\n    print(\"\\nCheck Django admin or a custom view for full functionality with the autocomplete URL.\")\n","lang":"python","description":"This quickstart demonstrates setting up a basic autocomplete for a `ForeignKey` field in Django using DAL. It involves defining a model, creating an autocomplete view (`CountryAutocomplete`) to serve data, and configuring a form (`CityForm`) to use the `Select2QuerySetView` widget, linking it to the autocomplete URL. Remember to include `dal` and `dal_select2` in `INSTALLED_APPS` before your own application."},"warnings":[{"fix":"Refer to the official DAL 3.x documentation for migration steps. The primary change involves using `dal_select2.widgets` for form fields and creating explicit `dal_select2.views` for data endpoints, rather than a monolithic `autocomplete_light.register`.","message":"Major API changes when upgrading from Django Autocomplete Light 2.x to 3.x. The `autocomplete_light.shortcuts` API was removed, and the way autocompletes are defined and integrated into forms and views was significantly refactored.","severity":"breaking","affected_versions":"2.x to 3.x"},{"fix":"Ensure your `settings.py` `INSTALLED_APPS` includes `dal` and `dal_select2` at the top, like: `INSTALLED_APPS = ['dal', 'dal_select2', 'your_app', ...]`.","message":"Incorrect `INSTALLED_APPS` ordering. `dal` and `dal_select2` must be listed in `INSTALLED_APPS` BEFORE any of your apps that use them.","severity":"gotcha","affected_versions":"3.x"},{"fix":"When defining your form widget, ensure the `url` parameter (e.g., `url=reverse_lazy('my-autocomplete')`) correctly references the name of your `path` for the autocomplete view in your `urls.py`.","message":"URL configuration mismatch between the form widget and the autocomplete view. The `url` parameter in `Select2QuerySetView` must point to a valid URL pattern for your autocomplete view.","severity":"gotcha","affected_versions":"3.x"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}