### Run Sample App Setup Source: https://github.com/codingjoe/django-select2/blob/main/example/README.md Clones the Django Select2 repository, navigates to the example directory, installs requirements, applies migrations, creates a superuser, and starts the development server. ```bash git clone https://github.com/codingjoe/django-select2.git cd django-select2/example python3 -m pip install -r requirements.txt python3 manage.py migrate python3 manage.py createsuperuser # follow the instructions to create a superuser python3 manage.py runserver # follow the instructions and open your browser ``` -------------------------------- ### Install django-select2 Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md Install the django-select2 package using pip. ```bash python3 -m pip install django-select2 ``` -------------------------------- ### Install Django-Select2 and Configure Settings Source: https://context7.com/codingjoe/django-select2/llms.txt Add 'django_select2' to INSTALLED_APPS. Configure a persistent cache backend for Model widgets, as DummyCache or LocMemCache are not suitable for production. ```python INSTALLED_APPS = [ "django.contrib.admin", # … other apps … "django_select2", ] # For Model widgets: configure a persistent shared cache. # DummyCache will NOT work. LocMemCache works only on single-server setups. CACHES = { "default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"}, "select2": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/2", "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"}, }, } SELECT2_CACHE_BACKEND = "select2" ``` -------------------------------- ### Install Redis Server Source: https://github.com/codingjoe/django-select2/blob/main/example/README.md Installs Redis server on Debian-based systems or macOS using Homebrew. Redis is required for caching purposes. ```bash # Debian sudo apt-get install redis-server -y # macOS brew install redis ``` -------------------------------- ### Install Binary Dependencies Source: https://github.com/codingjoe/django-select2/blob/main/CONTRIBUTING.rst Install required binary dependencies for Debian and macOS systems before editing Python code. ```bash # Debian sudo apt install -y gettext graphviz google-chrome-stable # macOS brew install -y gettext graphviz google-chrome-stable ``` -------------------------------- ### Configure Redis Cache for Select2 Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md Configure a Redis cache backend for django-select2, essential for multi-server setups. This example uses django-redis. ```python CACHES = { # … default cache config and others "select2": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", }, } } # Tell select2 which cache configuration to use: SELECT2_CACHE_BACKEND = "select2" ``` -------------------------------- ### Configure Django-Select2 Cache Backend Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Example of settings.py to configure Django's cache backend for Django-Select2, recommending a separate Redis instance for production. ```python CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } }, 'select2': { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } } # Set the cache backend to select2 SELECT2_CACHE_BACKEND = 'select2' ``` -------------------------------- ### Construct Full Path for Select2 Language File Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Example demonstrating how to construct the full path for a Select2 language file using Django's settings and translation utilities. ```python from django.utils import translations full_path = "{i18n_path}/{language_code}.js".format( i18n_path=settings.DJANGO_SELECT2_I18N, language_code=translations.get_language(), ) ``` -------------------------------- ### AutoResponseView JSON Response Example Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md This is an example of the JSON response structure returned by AutoResponseView for heavy model widgets. ```json { 'results': [ { 'text': "foo", 'id': 123 } ], 'more': true } ``` -------------------------------- ### Automatic Initialization of Select2 Widgets Source: https://context7.com/codingjoe/django-select2/llms.txt The bundled `django_select2.js` automatically initializes all elements with the class `.django-select2` on DOM ready. Elements with `.django-select2-heavy` also get AJAX functionality wired up. ```javascript // Automatic initialization on page load (no action needed): // All get AJAX wired up. ``` -------------------------------- ### Implement value_from_datadict for ModelSelect2TagWidget Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Implement value_from_datadict to handle the creation of new objects when using ModelSelect2TagWidget. This example assumes a 'title' field for new object creation. ```python class MyModelSelect2TagWidget(ModelSelect2TagWidget): queryset = MyModel.objects.all() def value_from_datadict(self, data, files, name): '''Create objects for given non-pimary-key values. Return list of all primary keys.''' values = set(super().value_from_datadict(data, files, name)) # This may only work for MyModel, if MyModel has title field. # You need to implement this method yourself, to ensure proper object creation. pks = self.queryset.filter(**{'pk__in': list(values)}).values_list('pk', flat=True) pks = set(map(str, pks)) cleaned_values = list(pks) for val in values - pks: cleaned_values.append(self.queryset.create(title=val).pk) return cleaned_values ``` -------------------------------- ### AutoResponseView Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md A Django view that handles requests from heavy model widgets, supporting only the GET method. It returns JSON responses with results rendered by the widget's `result_from_instance` method. ```APIDOC ### *class* django_select2.views.AutoResponseView(**kwargs) Bases: `BaseListView` View that handles requests from heavy model widgets. The view only supports HTTP’s GET method. #### get(request, *args, **kwargs) Return a `django.http.JsonResponse`. Each result will be rendered by the widget’s [`django_select2.forms.ModelSelect2Mixin.result_from_instance()`](#django_select2.forms.ModelSelect2Mixin.result_from_instance) method. ### Example: ```json { "results": [ { "text": "foo", "id": 123 } ], "more": true } ``` #### get_queryset() Get QuerySet from cached widget. #### get_paginate_by(queryset) Paginate response by size of widget’s max_results parameter. ``` -------------------------------- ### Compile Sphinx Documentation Source: https://github.com/codingjoe/django-select2/blob/main/CONTRIBUTING.rst Compile the Sphinx documentation into HTML format using 'uv' to run sphinx-build. The -W flag will treat warnings as errors. ```bash uv run sphinx-build -W -b doctest -b html docs docs/_build/html ``` -------------------------------- ### Basic HeavySelect2Widget Usage Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Demonstrates how to use HeavySelect2Widget by specifying a data view name or a direct URL for AJAX data. ```python class MyWidget(HeavySelect2Widget): data_view = 'my_view_name' ``` ```python class MyForm(forms.Form): my_field = forms.ChoiceField( widget=HeavySelect2Widget( data_url='/url/to/json/response' ) ) ``` -------------------------------- ### Use Select2Widget for Single Choice Fields Source: https://context7.com/codingjoe/django-select2/llms.txt Replace standard Django Select widgets with Select2Widget for single-choice fields. This widget renders all options client-side and requires no AJAX setup. ```python from django import forms from django_select2.forms import Select2Widget PRIORITY_CHOICES = [ ("low", "Low"), ("medium", "Medium"), ("high", "High"), ("critical", "Critical"), ] # As a standalone ChoiceField widget class TicketForm(forms.Form): priority = forms.ChoiceField( choices=PRIORITY_CHOICES, widget=Select2Widget(attrs={"data-placeholder": "Select priority…”}), required=False, ) # As a ModelForm Meta widget override from myapp.models import Ticket class TicketModelForm(forms.ModelForm): class Meta: model = Ticket fields = ["priority", "status"] widgets = { "priority": Select2Widget, "status": Select2Widget, } ``` -------------------------------- ### Load Form Media in Templates Source: https://context7.com/codingjoe/django-select2/llms.txt Ensure form media (CSS and JS) are loaded correctly in your HTML template. CSS should be in the , and JavaScript should be placed after jQuery. ```html {{ form.media.css }}
{% csrf_token %} {{ form.as_p }}
{{ form.media.js }} ``` -------------------------------- ### result_from_instance(obj, request) Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md This method returns a dictionary representing an object, which can be overridden to customize the output for AutoResponseView. The request object passed corresponds to the one sent by the widget. ```APIDOC ## result_from_instance(obj, request) ### Description Return a dictionary representing the object. Can be overridden to change the result returned by [`AutoResponseView`](#django_select2.views.AutoResponseView) for each object. The request passed in will correspond to the request sent to the [`AutoResponseView`](#django_select2.views.AutoResponseView) by the widget. ### Example usage: ```python class MyWidget(ModelSelect2Widget): def result_from_instance(obj, request): return { 'id': obj.pk, 'text': self.label_from_instance(obj), 'extra_data': obj.extra_data, } ``` ``` -------------------------------- ### Run Tests with Uvicorn Source: https://github.com/codingjoe/django-select2/blob/main/CONTRIBUTING.rst Execute the project's tests using the 'uv' command to run pytest. ```bash uv run pytest ``` -------------------------------- ### ModelSelect2Mixin.label_from_instance() Source: https://context7.com/codingjoe/django-select2/llms.txt Override to customize the display text rendered for each option in the dropdown and in the selected value. ```APIDOC ## `ModelSelect2Mixin.label_from_instance()` Override to customize the display text rendered for each option in the dropdown and in the selected value. ```python from django_select2.forms import ModelSelect2Widget from myapp.models import User, Product class UserWidget(ModelSelect2Widget): model = User search_fields = ["username__icontains", "email__icontains"] def label_from_instance(self, obj): return f"{obj.get_full_name()} ({obj.email})" class ProductWidget(ModelSelect2Widget): model = Product search_fields = ["name__icontains", "sku__icontains"] def label_from_instance(self, obj): return f"[{obj.sku}] {obj.name} — ${obj.price:.2f}" ``` ``` -------------------------------- ### Customizing Display Text with label_from_instance Source: https://context7.com/codingjoe/django-select2/llms.txt Customize the display text for each option and selected value by overriding the label_from_instance method. This method takes an object instance and should return a string representation. ```python from django_select2.forms import ModelSelect2Widget from myapp.models import User, Product class UserWidget(ModelSelect2Widget): model = User search_fields = ["username__icontains", "email__icontains"] def label_from_instance(self, obj): return f"{obj.get_full_name()} ({obj.email})" class ProductWidget(ModelSelect2Widget): model = Product search_fields = ["name__icontains", "sku__icontains"] def label_from_instance(self, obj): return f"[{obj.sku}] {obj.name} — ${obj.price:.2f}" ``` -------------------------------- ### ModelSelect2TagWidget for Tagging and Creation Source: https://context7.com/codingjoe/django-select2/llms.txt Employ ModelSelect2TagWidget for model-backed tagging inputs that allow creating new instances. It requires overriding value_from_datadict to handle new tag creation logic, returning a list of PKs for both existing and newly created items. ```python from django import forms from django_select2.forms import ModelSelect2TagWidget from myapp.models import Album, Genre class GenreTagWidget(ModelSelect2TagWidget): model = Genre search_fields = ["title__icontains"] def value_from_datadict(self, data, files, name): """Create new Genre objects for values that are not existing PKs.""" values = set(super().value_from_datadict(data, files, name)) existing_pks = set( map(str, self.get_queryset().filter(pk__in=list(values)).values_list("pk", flat=True)) ) cleaned = list(existing_pks) for val in values - existing_pks: # Create the new Genre and return its PK cleaned.append(self.get_queryset().create(title=val).pk) return cleaned class AlbumForm(forms.ModelForm): class Meta: model = Album fields = ["title", "genres"] widgets = {"genres": GenreTagWidget} ``` -------------------------------- ### Initialize Select2 with Custom Options Source: https://context7.com/codingjoe/django-select2/llms.txt Pass custom Select2 options to the `djangoSelect2()` plugin to configure behavior like placeholders, minimum input length, and language. ```javascript $('#my-select').djangoSelect2({ placeholder: 'Search…', minimumInputLength: 2, language: 'de', }); ``` -------------------------------- ### Implement AJAX-backed tagging with HeavySelect2TagWidget Source: https://context7.com/codingjoe/django-select2/llms.txt HeavySelect2TagWidget combines free-text tagging with AJAX result fetching. It's suitable for fields where users can create new tags or select existing ones dynamically. Configure with `data_view` and `attrs` for token separators. ```python from django_select2.forms import HeavySelect2TagWidget from django import forms class ArticleForm(forms.Form): related_topics = forms.MultipleChoiceField( widget=HeavySelect2TagWidget( data_view="topic-search", attrs={"data-token-separators": '[","]'}, ), choices=[], required=False, ) ``` -------------------------------- ### Add django_select2 to INSTALLED_APPS Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md Add 'django_select2' to your project's INSTALLED_APPS in settings.py. Ensure Django's admin app is also enabled. ```python INSTALLED_APPS = [ # other django apps… "django.contrib.admin", # other 3rd party apps… "django_select2", ] ``` -------------------------------- ### Create Django View to Render Form Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md A generic Django CreateView to render the BookForm, which includes the custom Select2 widgets. ```python # views.py from django.views import generic from . import forms, models class BookCreateView(generic.CreateView): model = models.Book form_class = forms.BookForm success_url = "/" ``` -------------------------------- ### Include Django Select2 URLs Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md Add this path to your project's urls.py to enable Django Select2 functionality. Ensure it's correctly placed within your urlpatterns. ```python from django.urls import include, path from . import views urlpatterns = [ # … other patterns path("select2/", include("django_select2.urls")), # … other patterns path("book/create", views.BookCreateView.as_view(), name="book-create"), ] ``` -------------------------------- ### Initialize Select2 Fields with jQuery Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Use this jQuery plugin to initialize select2 fields, handling both normal and heavy fields. Replace existing .select2 invocations with .djangoSelect2. ```javascript $('.django-select2').djangoSelect2(); ``` -------------------------------- ### Select2 Configuration Settings Source: https://context7.com/codingjoe/django-select2/llms.txt These settings configure the Select2 CSS files, theme, and i18n path. The JSON encoder can be customized for non-standard model primary key types. ```python SELECT2_CSS = ["admin/css/vendor/select2/select2.min.css"] # Custom theme: SELECT2_CSS = ["assets/css/select2.css", "assets/css/select2-bootstrap5.css"] # Select2 theme name (default: "default") SELECT2_THEME = "bootstrap-5" # Base path for Select2 i18n files (default: Django admin's i18n path) SELECT2_I18N_PATH = "admin/js/vendor/select2/i18n" # Custom JSON encoder for the AutoResponseView response (default: DjangoJSONEncoder) # Useful when model PKs are UUIDs or other non-standard types SELECT2_JSON_ENCODER = "myapp.encoders.CustomJSONEncoder" ``` -------------------------------- ### ModelSelect2TagWidget Source: https://context7.com/codingjoe/django-select2/llms.txt Model-backed tag widget that supports creating new model instances from user-typed text. Requires a custom `value_from_datadict` to handle new tag creation. ```APIDOC ## `ModelSelect2TagWidget` Model-backed tag widget that supports creating new model instances from user-typed text. Requires a custom `value_from_datadict` to handle new tag creation. ```python from django import forms from django_select2.forms import ModelSelect2TagWidget from myapp.models import Album, Genre class GenreTagWidget(ModelSelect2TagWidget): model = Genre search_fields = ["title__icontains"] def value_from_datadict(self, data, files, name): """Create new Genre objects for values that are not existing PKs.""" values = set(super().value_from_datadict(data, files, name)) existing_pks = set( map(str, self.get_queryset().filter(pk__in=list(values)).values_list("pk", flat=True)) ) cleaned = list(existing_pks) for val in values - existing_pks: # Create the new Genre and return its PK cleaned.append(self.get_queryset().create(title=val).pk) return cleaned class AlbumForm(forms.ModelForm): class Meta: model = Album fields = ["title", "genres"] widgets = {"genres": GenreTagWidget} ``` ``` -------------------------------- ### Configure Select2 Internationalization Path Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Update the SELECT2_I18N_PATH setting in settings.py to point to a custom directory for Select2 internationalization files. ```python SELECT2_I18N_PATH = 'assets/js/i18n' ``` -------------------------------- ### Implement AJAX-powered single-select with HeavySelect2Widget Source: https://context7.com/codingjoe/django-select2/llms.txt Use HeavySelect2Widget for AJAX-powered single-select fields. It requires a custom view to handle search queries and return results. You can specify the view using `data_view` or a literal URL with `data_url`. ```python from django import forms from django.http import JsonResponse from django.views import View from django_select2.forms import HeavySelect2Widget # Custom AJAX view class UserSearchView(View): def get(self, request): term = request.GET.get("term", "") users = User.objects.filter(username__icontains=term).values("pk", "username")[:25] results = [{"id": u["pk"], "text": u["username"]} for u in users] return JsonResponse({"results": results, "more": False}) # urls.py # path("users/search/", UserSearchView.as_view(), name="user-search"), # Form using data_view (URL name) or data_url (literal URL) class AssignmentForm(forms.Form): assignee = forms.ChoiceField( widget=HeavySelect2Widget(data_view="user-search"), choices=[], ) # Or use data_url directly class AssignmentFormAlt(forms.Form): assignee = forms.ChoiceField( widget=HeavySelect2Widget(data_url="/users/search/"), choices=[], ) ``` -------------------------------- ### Configure ModelSelect2Widget in a Form Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Instantiate ModelSelect2Widget directly within a Form's field definition, providing model and search_fields. ```python class MyForm(forms.Form): my_choice = forms.ChoiceField( widget=ModelSelect2Widget( model=MyOtherModel, search_fields=['title__icontains'] ) ) ``` -------------------------------- ### Implement AJAX-powered multi-select with HeavySelect2MultipleWidget Source: https://context7.com/codingjoe/django-select2/llms.txt HeavySelect2MultipleWidget enables AJAX-powered multi-select fields, similar to HeavySelect2Widget but allowing multiple selections. It supports configuration options like `data_minimum_input_length`. ```python from django import forms from django_select2.forms import HeavySelect2MultipleWidget class ProjectForm(forms.Form): title = forms.CharField(max_length=200) members = forms.MultipleChoiceField( widget=HeavySelect2MultipleWidget( data_view="user-search", attrs={"data-minimum-input-length": 0}, # show results immediately ), choices=[], required=False, ) tags = forms.MultipleChoiceField( widget=HeavySelect2MultipleWidget( data_url="/api/tags/search/", ), choices=[], ) ``` -------------------------------- ### Configuration Settings Source: https://context7.com/codingjoe/django-select2/llms.txt Customize django-select2 behavior through Django settings. All settings are prefixed with `SELECT2_` and should be placed in your `settings.py` file. ```APIDOC ## Configuration Settings All settings are prefixed with `SELECT2_` and placed in `settings.py`. ### Settings Reference: ```python # settings.py — full reference with defaults shown # Cache backend alias for storing widget state (default: "default") SELECT2_CACHE_BACKEND = "select2" # Cache key prefix (default: "select2_") SELECT2_CACHE_PREFIX = "myapp_select2_" # Select2 JS file(s) — default points to Django admin's bundled Select2 SELECT2_JS = ["admin/js/vendor/select2/select2.full.min.js"] # Serve from CDN instead: SELECT2_JS = ["https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"] # Disable (you load Select2 yourself): SELECT2_JS = [] ``` ``` -------------------------------- ### ModelSelect2Mixin.result_from_instance() Source: https://context7.com/codingjoe/django-select2/llms.txt Override to enrich the JSON payload returned by `AutoResponseView` for each result — useful when the client-side JavaScript needs extra data attributes beyond `id` and `text`. ```APIDOC ## `ModelSelect2Mixin.result_from_instance()` Override to enrich the JSON payload returned by `AutoResponseView` for each result — useful when the client-side JavaScript needs extra data attributes beyond `id` and `text`. ```python from django_select2.forms import ModelSelect2Widget from myapp.models import City class CityWidget(ModelSelect2Widget): model = City search_fields = ["name__icontains"] def result_from_instance(self, obj, request): return { "id": obj.pk, "text": obj.name, "country": str(obj.country), "timezone": obj.timezone, "population": obj.population, } # The AutoResponseView JSON response becomes: # { # "results": [ # {"id": 42, "text": "Berlin", "country": "Germany", # "timezone": "Europe/Berlin", "population": 3769000} # ], # "more": false # } ``` ``` -------------------------------- ### URL Configuration Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Instructions on how to include django-select2's URL configuration in your Django project's main URLconf, necessary for using 'Model' fields. ```APIDOC ## URLs Django-Select2 URL configuration. Add django_select to your `urlconf` **if** you use any ‘Model’ fields: ```python from django.urls import path, include path('select2/', include('django_select2.urls')), ``` ``` -------------------------------- ### Include django_select2 URLs Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md Include django_select2's URL patterns in your project's root URL configuration. ```python from django.urls import include, path urlpatterns = [ # other patterns… path("select2/", include("django_select2.urls")), # other patterns… ] ``` -------------------------------- ### Render Book Form with Select2 Source: https://github.com/codingjoe/django-select2/blob/main/example/example/templates/example/book_form.html Renders a Django form for creating a book, including Select2's CSS and JavaScript for enhanced select inputs. Ensure Select2 is properly configured in your Django project. ```html {% load static %} Create Book {{ form.media.css }} input, select {width: 100%} Create a new Book ================= {% csrf_token %} {{ form.as_p }} {{ form.media.js }} ``` -------------------------------- ### Registering AutoResponseView URLs Source: https://context7.com/codingjoe/django-select2/llms.txt Include `django_select2.urls` in your project's `urls.py` to automatically register the `AutoResponseView` endpoint. You can reverse the URL name for manual reversal. ```python # The view is registered automatically when you include django_select2.urls. # urls.py from django.urls import include, path urlpatterns = [ path("select2/", include("django_select2.urls")), ] # To inspect the URL name for manual reversal: from django.urls import reverse url = reverse("django_select2:auto-json") # → "/select2/fields/auto.json" ``` -------------------------------- ### Use Select2TagWidget for Tagging Input Source: https://context7.com/codingjoe/django-select2/llms.txt Employ Select2TagWidget to enable users to input free-text values and dynamically create new options. Tokens are typically separated by commas and spaces. ```python from django import forms from django_select2.forms import Select2TagWidget class ArticleForm(forms.Form): keywords = forms.CharField( widget=Select2TagWidget, required=False, ) ``` -------------------------------- ### Django Select2 Configuration Settings Source: https://context7.com/codingjoe/django-select2/llms.txt Configure `django-select2` by setting `SELECT2_` prefixed variables in your `settings.py`. Defaults are provided for cache backend, cache prefix, and Select2 JS file paths. ```python # settings.py — full reference with defaults shown # Cache backend alias for storing widget state (default: "default") SELECT2_CACHE_BACKEND = "select2" # Cache key prefix (default: "select2_") SELECT2_CACHE_PREFIX = "myapp_select2_" # Select2 JS file(s) — default points to Django admin's bundled Select2 SELECT2_JS = ["admin/js/vendor/select2/select2.full.min.js"] # Serve from CDN instead: SELECT2_JS = ["https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"] # Disable (you load Select2 yourself): SELECT2_JS = [] ``` -------------------------------- ### Create Django Model Form with Select2 Widgets Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md Create a Django ModelForm and assign the custom Select2 widgets to the respective model fields. ```python # forms.py from django import forms from django_select2 import forms as s2forms from . import models class AuthorWidget(s2forms.ModelSelect2Widget): search_fields = [ "username__icontains", "email__icontains", ] class CoAuthorsWidget(s2forms.ModelSelect2MultipleWidget): search_fields = [ "username__icontains", "email__icontains", ] class BookForm(forms.ModelForm): class Meta: model = models.Book fields = "__all__" widgets = { "author": AuthorWidget, "co_authors": CoAuthorsWidget, } ``` -------------------------------- ### Book Form Template with Select2 Media Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md This HTML template demonstrates how to include Django Select2's CSS and JavaScript. Ensure {{ form.media.css }} and {{ form.media.js }} are present in your template's head and body respectively. ```html Create Book {{ form.media.css }}

Create a new Book

{% csrf_token %} {{ form.as_p }}
{{ form.media.js }} ``` -------------------------------- ### Configure Select2 Options via JavaScript Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Pass Select2 options directly in JavaScript when initializing the djangoSelect2 plugin. This allows for dynamic configuration of Select2 behavior. ```javascript $('.django-select2').djangoSelect2({ minimumInputLength: 0, placeholder: 'Select an option', }); ``` -------------------------------- ### Customize Select2 CSS File Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Adjust the SELECT2_CSS setting in settings.py to specify custom CSS files for Select2, including themes, or disable loading by setting it to an empty list. ```python SELECT2_CSS = ['assets/css/select2.css'] ``` ```python SELECT2_CSS = [ 'assets/css/select2.css', 'assets/css/select2-theme.css', ] ``` ```python SELECT2_CSS = [] ``` -------------------------------- ### Customizing ModelSelect2 Widget Label Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Override the label_from_instance method to customize how model objects are displayed as choice labels in a ModelSelect2 widget. ```python class MyWidget(ModelSelect2Widget): def label_from_instance(obj): return str(obj.title).upper() ``` -------------------------------- ### Select2Mixin Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md The base mixin for all Select2 widgets. It handles rendering data attributes and adding static form media. ```APIDOC ## class django_select2.forms.Select2Mixin Bases: `object` ### Properties - `css_class_name` (string): Defaults to 'django-select2'. - `theme` (string): Defaults to None. - `empty_label` (string): Defaults to ''. - `i18n_name` (property): Name of the i18n file for the current language. - `media` (property): Construct Media as a dynamic property. See https://docs.djangoproject.com/en/stable/topics/forms/media/#media-as-a-dynamic-property ### Methods - `build_attrs(base_attrs, extra_attrs=None)`: Add select2 data attributes. - `optgroups(name, value, attrs=None)`: Add empty option for clearable selects. ``` -------------------------------- ### Secure Select2 JSON Endpoint with LoginRequiredMixin Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Create a secure JSON endpoint for Select2 data that requires user authentication. This prevents unauthorized access to sensitive data. ```python class UserSelect2View(LoginRequiredMixin, AutoResponseView): pass ``` -------------------------------- ### Configure ModelSelect2Widget in a ModelForm Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Use ModelSelect2Widget in a ModelForm by specifying it in the widgets dictionary. ```python class MyWidget(ModelSelect2Widget): search_fields = [ 'title__icontains', ] class MyModelForm(forms.ModelForm): class Meta: model = MyModel fields = ('my_field', ) widgets = { 'my_field': MyWidget, } ``` -------------------------------- ### ModelSelect2Mixin Search Fields Configuration Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Configure model lookups for filtering QuerySets in ModelSelect2 widgets. Use field names with '__icontains' for case-insensitive containment searches. ```python search_fields = [ 'title__icontains', ] ``` -------------------------------- ### Create Django Select2 Widgets Source: https://github.com/codingjoe/django-select2/blob/main/docs/index.md Define custom Select2 widgets for ForeignKey and ManyToMany fields, specifying search fields for autocomplete. ```python # forms.py from django import forms from django_select2 import forms as s2forms from . import models class AuthorWidget(s2forms.ModelSelect2Widget): search_fields = [ "username__icontains", "email__icontains", ] class CoAuthorsWidget(s2forms.ModelSelect2MultipleWidget): search_fields = [ "username__icontains", "email__icontains", ] ``` -------------------------------- ### ModelSelect2MultipleWidget Source: https://context7.com/codingjoe/django-select2/llms.txt Model-backed multi-select AJAX widget that works identically to ModelSelect2Widget but returns and accepts multiple values. ```APIDOC ## `ModelSelect2MultipleWidget` Model-backed multi-select AJAX widget. Works identically to `ModelSelect2Widget` but returns and accepts multiple values. ```python from django import forms from django_select2.forms import ModelSelect2MultipleWidget from myapp.models import Album, Artist, Genre class GenreWidget(ModelSelect2MultipleWidget): model = Genre search_fields = ["title__icontains"] class AlbumForm(forms.ModelForm): class Meta: model = Album fields = ["title", "artist", "genres", "featured_artists"] widgets = { "genres": GenreWidget, "featured_artists": ModelSelect2MultipleWidget( queryset=Artist.objects.filter(is_active=True), search_fields=["title__icontains"], max_results=50, ), } # Standalone form with explicit queryset class PlaylistForm(forms.Form): tracks = forms.ModelMultipleChoiceField( queryset=Track.objects.all(), widget=ModelSelect2MultipleWidget( queryset=Track.objects.select_related("artist"), search_fields=["title__icontains", "artist__title__icontains"], ), ) ``` ``` -------------------------------- ### Include Django-Select2 URLs Source: https://context7.com/codingjoe/django-select2/llms.txt Include the django_select2 URLs in your project's urls.py. This is required for Model and Heavy widgets to function correctly. ```python from django.urls import include, path urlpatterns = [ # … other patterns … path("select2/", include("django_select2.urls")), ] ``` -------------------------------- ### Select2 Configuration Settings Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Configuration options for django-select2, which can be set in your Django project's settings.py file to customize behavior, caching, and static file paths. ```APIDOC ## Configuration Settings ### `Select2Conf` Class This class outlines the available settings for django-select2. #### `CACHE_BACKEND` *Default*: `'default'` Specifies the Django cache backend to be used by django-select2 for maintaining consistent state across multiple machines. Example configuration shows how to set up a separate Redis cache for select2. #### `CACHE_PREFIX` *Default*: `'select2_'` An optional prefix to isolate django-select2's cache entries if the cache backend does not support multiple databases. #### `JS` *Default*: `['admin/js/vendor/select2/select2.full.min.js']` The URI for the Select2 JavaScript file. This can be customized to point to a different version or a locally served file. An empty list `[]` will prevent django-select2 from loading any JS. #### `CSS` *Default*: `['admin/css/vendor/select2/select2.min.css']` The URI for the Select2 CSS file. Similar to `JS`, this can be customized for different versions or local serving. Multiple CSS files can be included for theming. An empty list `[]` will prevent django-select2 from loading any CSS. #### `THEME` *Default*: `'default'` Allows selection of custom themes for Select2 to match the application's design. #### `I18N_PATH` *Default*: `'admin/js/vendor/select2/i18n'` The base URI for Select2 internationalization (i18n) files. Can be customized to serve i18n files from local static resources. #### `I18N_AVAILABLE_LANGUAGES` *Default*: A comprehensive list of ISO 639-1 language codes. Defines the list of supported languages for Select2. If the current language setting matches an entry in this list, the corresponding translation file will be loaded. #### `JSON_ENCODER` *Default*: `'django.core.serializers.json.DjangoJSONEncoder'` A JSON encoder used for generating API responses for model widgets. Useful for handling custom primary key types that are not serializable by the default encoder. ### `Meta` Class #### `prefix` *Default*: `'SELECT2'` Sets a prefix for all django-select2 related settings. ``` -------------------------------- ### JavaScript Error Handling Source: https://github.com/codingjoe/django-select2/blob/main/tests/testapp/templates/form.html Sets up a global JavaScript error handler to capture and report any errors occurring on the page. The error message is then set as an attribute on the body element. ```javascript window.onerror = function (msg) { $("body").attr("JSError", msg); } {{ form.media.js }} ``` -------------------------------- ### HeavySelect2Widget Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Select2 widget with AJAX support that registers itself to Django’s Cache. It inherits from HeavySelect2Mixin and Select2Widget. ```APIDOC ## Class: HeavySelect2Widget ### Description Select2 widget with AJAX support that registers itself to Django’s Cache. ### Usage Example ```python class MyWidget(HeavySelect2Widget): data_view = 'my_view_name' ``` ```python class MyForm(forms.Form): my_field = forms.ChoiceField( widget=HeavySelect2Widget( data_url='/url/to/json/response' ) ) ``` ### Properties - **media**: Construct Media as a dynamic property. ``` -------------------------------- ### Select2AdminMixin Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md A Select2 mixin that utilizes Django's own select template. ```APIDOC ## class django_select2.forms.Select2AdminMixin Bases: `object` ### Properties - `theme` (string): Defaults to 'admin-autocomplete'. - `media` (property): Construct Media as a dynamic property. ``` -------------------------------- ### HeavySelect2MultipleWidget Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Select2 multi select widget similar to HeavySelect2Widget. It inherits from HeavySelect2Mixin and Select2MultipleWidget. ```APIDOC ## Class: HeavySelect2MultipleWidget ### Description Select2 multi select widget similar to `HeavySelect2Widget`. ### Properties - **media**: Construct Media as a dynamic property. ``` -------------------------------- ### ModelSelect2Mixin Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Widget mixin that provides attributes and methods for AutoResponseView. It is used for model-based select widgets. ```APIDOC ## Class: ModelSelect2Mixin ### Description Widget mixin that provides attributes and methods for `AutoResponseView`. ### Attributes - **empty_label**: Label for empty choices. - **model**: Django model to use. - **queryset**: QuerySet to use for choices. - **search_fields** ([]): Model lookups used to filter the QuerySet. - **max_results** (25): Maximal results returned by `AutoResponseView`. ### Methods #### set_to_cache() Add widget’s attributes to Django’s cache. Split the QuerySet, to not pickle the result set. #### filter_queryset(request, term, queryset=None, **dependent_fields) Return QuerySet filtered by `search_fields` matching the passed term. * **Parameters:** * **request** (*django.http.request.HttpRequest*) – The request is being passed from the JSON view and can be used to dynamically alter the response queryset. * **term** (*str*) – Search term * **queryset** (*django.db.models.query.QuerySet*) – QuerySet to select choices from. * **&&dependent_fields** – Dependent fields and their values. If you want to inherit from ModelSelect2Mixin and later call to this method, be sure to pop everything from keyword arguments that is not a dependent field. * **Returns:** Filtered QuerySet * **Return type:** QuerySet #### get_queryset() Return QuerySet based on `queryset` or `model`. * **Returns:** QuerySet of available choices. * **Return type:** QuerySet #### get_search_fields() Return list of lookup names. #### optgroups(name, value, attrs=None) Return only selected options and set QuerySet from ModelChoicesIterator. #### label_from_instance(obj) Return option label representation from instance. Can be overridden to change the representation of each choice. * **Parameters:** **obj** (*django.db.models.Model*) – Instance of Django Model. * **Returns:** Option label. * **Return type:** str ``` -------------------------------- ### Initialize Select2 Widget Manually Source: https://context7.com/codingjoe/django-select2/llms.txt Use the `djangoSelect2()` jQuery plugin to initialize Select2 widgets. This is useful for widgets added dynamically after the initial page load. ```javascript $('#my-select').djangoSelect2(); ``` -------------------------------- ### AutoResponseView AJAX Endpoint Source: https://context7.com/codingjoe/django-select2/llms.txt The `AutoResponseView` handles AJAX requests for Model widgets, automatically filtering and paginating results. It is registered at `/select2/fields/auto.json`. ```APIDOC ## `AutoResponseView` — Built-in AJAX Endpoint `AutoResponseView` (registered at `select2/fields/auto.json`) handles all Model widget AJAX requests automatically. It recovers the cached widget configuration, delegates to `filter_queryset`, paginates results, and returns a JSON response. ### Request Example: ``` GET /select2/fields/auto.json?term=john&page=1&field_id= ``` ### Response Example: ```json { "results": [ {"id": 1, "text": "John Smith"}, {"id": 7, "text": "Johnny Walker"} ], "more": false } ``` ### URL Configuration: ```python # The view is registered automatically when you include django_select2.urls. # urls.py from django.urls import include, path urlpatterns = [ path("select2/", include("django_select2.urls")), ] # To inspect the URL name for manual reversal: from django.urls import reverse url = reverse("django_select2:auto-json") # → "/select2/fields/auto.json" ``` ``` -------------------------------- ### Configure Form for Multi-Dependent Select2 Widgets Source: https://github.com/codingjoe/django-select2/blob/main/docs/extra.md Set up a form with a select field that depends on multiple other select fields. The 'dependent_fields' dictionary maps multiple form fields to their corresponding model fields. ```python class SomeForm(forms.Form): field1 = forms.ModelChoiceField( widget=ModelSelect2Widget( ) ) field2 = forms.ModelChoiceField( widget=ModelSelect2Widget( ) ) field3 = forms.ModelChoiceField( widget=ModelSelect2Widget( dependent_fields={'field1': 'field1', 'field2': 'field2'}, ) ) ``` -------------------------------- ### HeavySelect2TagWidget Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Select2 tag widget. It inherits from HeavySelect2Mixin and Select2TagWidget. ```APIDOC ## Class: HeavySelect2TagWidget ### Description Select2 tag widget. ### Properties - **media**: Construct Media as a dynamic property. ``` -------------------------------- ### ModelSelect2MultipleWidget for Multiple Selections Source: https://context7.com/codingjoe/django-select2/llms.txt Use ModelSelect2MultipleWidget for model-backed multi-select fields with AJAX support. It functions similarly to ModelSelect2Widget but handles multiple values. Configure with model, search_fields, and optionally queryset and max_results. ```python from django import forms from django_select2.forms import ModelSelect2MultipleWidget from myapp.models import Album, Artist, Genre class GenreWidget(ModelSelect2MultipleWidget): model = Genre search_fields = ["title__icontains"] class AlbumForm(forms.ModelForm): class Meta: model = Album fields = ["title", "artist", "genres", "featured_artists"] widgets = { "genres": GenreWidget, "featured_artists": ModelSelect2MultipleWidget( queryset=Artist.objects.filter(is_active=True), search_fields=["title__icontains"], max_results=50, ), } # Standalone form with explicit queryset class PlaylistForm(forms.Form): tracks = forms.ModelMultipleChoiceField( queryset=Track.objects.all(), widget=ModelSelect2MultipleWidget( queryset=Track.objects.select_related("artist"), search_fields=["title__icontains", "artist__title__icontains"], ), ) ``` -------------------------------- ### Adapt Select2TagWidget for PostgreSQL ArrayField Source: https://context7.com/codingjoe/django-select2/llms.txt This widget adapts the Select2TagWidget for use with Django's PostgreSQL ArrayField. It handles the conversion between a list of values and a comma-separated string for the ArrayField. ```python from django.contrib.postgres.fields import ArrayField class ArrayFieldTagWidget(Select2TagWidget): """Adapts Select2TagWidget for use with ArrayField.""" def value_from_datadict(self, data, files, name): values = super().value_from_datadict(data, files, name) return ",".join(values) def optgroups(self, name, value, attrs=None): values = value[0].split(",") if value[0] else [] selected = set(values) subgroup = [ self.create_option(name, v, v, selected, i) for i, v in enumerate(values) ] return [(None, subgroup, 0)] class PostForm(forms.ModelForm): class Meta: model = Post fields = ["title", "tags"] widgets = {"tags": ArrayFieldTagWidget} ``` -------------------------------- ### Select2TagMixin Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Mixin to add select2 tag functionality, allowing dynamic creation of options from user input. ```APIDOC ## class django_select2.forms.Select2TagMixin Bases: `object` ### Methods - `build_attrs(base_attrs, extra_attrs=None)`: Add select2’s tag attributes. ``` -------------------------------- ### Django Form Rendering with Select2 Media Source: https://github.com/codingjoe/django-select2/blob/main/tests/testapp/templates/form.html Includes Django static files, Select2 CSS, sets a default width for select elements, and renders the form with a CSRF token. Ensure form.media.css and form.media.js are correctly configured in your Django settings. ```html {% load static %} {{ form.media.css }} select { width: 200px; } {% csrf_token %} {{ form }} ``` -------------------------------- ### Django-Select2 Widgets Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Overview of the widget types provided by django-select2, which are used to render choice fields with the Select2 JavaScript library. ```APIDOC ## Widgets Django-Select2 provides several types of widgets designed to integrate with Django's choice fields, enhancing them with the Select2 JavaScript library. ### Widget Types - **Light Widgets**: Typically used for simpler choice fields. - **Heavy Widgets**: Suitable for fields with a large number of choices, often involving AJAX lookups. - **Model Widgets**: Specifically designed for use with Django model fields, providing an easy way to select model instances. ``` -------------------------------- ### HeavySelect2Mixin Source: https://github.com/codingjoe/django-select2/blob/main/docs/django_select2.md Mixin that adds select2’s AJAX options and registers itself on Django’s cache. It provides attributes like data_view and data_url for AJAX configuration. ```APIDOC ## Class: HeavySelect2Mixin ### Description Mixin that adds select2’s AJAX options and registers itself on Django’s cache. ### Attributes - **data_view** (None): URL name for the data view. - **data_url** (None): URL for the data view. - **dependent_fields** ({}): Dictionary for dependent fields. ### Methods #### get_url() Return URL from instance or by reversing `data_view`. #### build_attrs(base_attrs, extra_attrs=None) Set select2’s AJAX attributes. #### render(*args, **kwargs) Render widget and register it in Django’s cache. #### set_to_cache() Add widget object to Django’s cache. You may need to overwrite this method, to pickle all information that is required to serve your JSON response view. ``` -------------------------------- ### Handle Dynamic Formsets with Select2 Source: https://context7.com/codingjoe/django-select2/llms.txt The `django_select2.js` plugin automatically handles Django's `formset:added` event to initialize Select2 widgets within newly added inline forms. ```javascript document.addEventListener('formset:added', (event) => { // django_select2.js already does this — shown here for reference only $(event.target).find('.django-select2').djangoSelect2(); }); ``` -------------------------------- ### AutoResponseView AJAX Endpoint Response Source: https://context7.com/codingjoe/django-select2/llms.txt The `AutoResponseView` handles AJAX requests for Model widgets, returning results in a paginated JSON format. The `field_id` parameter is a signed identifier for the widget configuration. ```json { "results": [ {"id": 1, "text": "John Smith"}, {"id": 7, "text": "Johnny Walker"} ], "more": false } ```