### Install django-select2 Package Source: https://django-select2.readthedocs.io/en/latest/_sources/index Command to install the django-select2 package using pip. This is the first step for setting up the library in a Django project. ```shell python3 -m pip install django-select2 ``` -------------------------------- ### Install Redis for Caching Source: https://django-select2.readthedocs.io/en/latest/index Installs Redis server and the django-redis Python client, necessary for persistent cache backends in multi-server setups. ```shell # Debian sudo apt-get install redis-server # macOS brew install redis # install Redis python client python3 -m pip install django-redis ``` -------------------------------- ### Install Django-Select2 Source: https://django-select2.readthedocs.io/en/latest/index Installs the django-select2 package using pip. Ensure you are using python3. ```shell python3 -m pip install django-select2 ``` -------------------------------- ### Install Redis Server Source: https://django-select2.readthedocs.io/en/latest/_sources/index Commands for installing Redis server on Debian and macOS. Redis is recommended as a persistent cache backend for django-select2 in multi-server environments. ```shell # Debian sudo apt-get install redis-server # macOS brew install redis ``` -------------------------------- ### Install Redis Python Client Source: https://django-select2.readthedocs.io/en/latest/_sources/index Command to install the django-redis Python client library using pip. This is required to use Redis as a cache backend for django-select2. ```shell python3 -m pip install django-redis ``` -------------------------------- ### Django-Select2: ModelSelect2Widget Example Usage Source: https://django-select2.readthedocs.io/en/latest/django_select2 Provides example implementations of ModelSelect2Widget within Django models and forms. It demonstrates how to configure search fields and integrate the widget into 'Meta' classes or directly in form field definitions. ```python class MyWidget(ModelSelect2Widget): search_fields = [ 'title__icontains', ] class MyModelForm(forms.ModelForm): class Meta: model = MyModel fields = ('my_field', ) widgets = { 'my_field': MyWidget, } # Or: class MyForm(forms.Form): my_choice = forms.ChoiceField( widget=ModelSelect2Widget( model=MyOtherModel, search_fields=['title__icontains'] ) ) ``` -------------------------------- ### JavaScript Initialization of Django-Select2 Source: https://django-select2.readthedocs.io/en/latest/django_select2 Guides on how to initialize Select2 fields using the provided JavaScript plugin, both automatically and manually. ```APIDOC ## JavaScript Initialization ### Description DjangoSelect2 automatically initializes Select2 fields when `{{ form.media }}` is included in your template. For dynamic forms or manual control, use the `djangoSelect2()` jQuery plugin. ### Method N/A (JavaScript usage) ### Endpoint N/A (JavaScript usage) ### Parameters N/A (JavaScript usage) ### Request Example ```javascript // Automatic initialization (include form.media in template) // Manual initialization $('.django-select2').djangoSelect2(); // With options $('.django-select2').djangoSelect2({ minimumInputLength: 0, placeholder: 'Select an option', }); ``` ### Response N/A (JavaScript usage) ``` -------------------------------- ### Configure Django-Select2 Options via JavaScript Source: https://django-select2.readthedocs.io/en/latest/django_select2 Demonstrates how to pass Select2 configuration options directly through JavaScript when initializing the widget. This example sets the minimum input length to 0 and defines a placeholder text for the select field. ```javascript $('.django-select2').djangoSelect2({ minimumInputLength: 0, placeholder: 'Select an option', }); ``` -------------------------------- ### Create Django Class-Based View for Book Creation Source: https://django-select2.readthedocs.io/en/latest/_sources/index Example Django CreateView to render the BookForm. This view uses the model and form defined previously to handle book creation requests. ```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 = "/" ``` -------------------------------- ### Define Django Model for Book Source: https://django-select2.readthedocs.io/en/latest/_sources/index Example Django model definition for a 'Book' with ForeignKey and ManyToManyField relationships to the user model. Used to demonstrate django-select2 widgets. ```python # models.py from django.conf import settings from django.db import models class Book(models.Model): author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) co_authors = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='co_authored_by') ``` -------------------------------- ### Create Django Forms with Select2 Widgets Source: https://django-select2.readthedocs.io/en/latest/_sources/index Example Django form definitions using custom ModelSelect2Widget and ModelSelect2MultipleWidget from django_select2. These widgets enhance ForeignKey and ManyToManyField selections. ```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, } ``` -------------------------------- ### AutoResponseView: Handle GET requests for Django-Select2 widgets Source: https://django-select2.readthedocs.io/en/latest/_modules/django_select2/views The AutoResponseView handles GET requests for Django-Select2 model widgets. It retrieves widget configurations, filters the queryset based on search terms and dependent fields, and returns results as a JSON response. The response includes 'results' (formatted instances) and 'more' (pagination indicator). ```python """JSONResponse views for model widgets.""" from django.core import signing from django.core.signing import BadSignature from django.http import Http404, JsonResponse from django.utils.module_loading import import_string from django.views.generic.list import BaseListView from .cache import cache from .conf import settings class AutoResponseView(BaseListView): """ View that handles requests from heavy model widgets. The view only supports HTTP's GET method. """ def get(self, request, *args, **kwargs): """ Return a :class:`.django.http.JsonResponse`. Each result will be rendered by the widget's :func:`django_select2.forms.ModelSelect2Mixin.result_from_instance` method. Example:: { 'results': [ { 'text': "foo", 'id': 123 } ], 'more': true } """ self.widget = self.get_widget_or_404() self.term = kwargs.get("term", request.GET.get("term", "")) self.object_list = self.get_queryset() context = self.get_context_data() return JsonResponse( { "results": [ self.widget.result_from_instance(obj, request) for obj in context["object_list"] ], "more": context["page_obj"].has_next(), }, encoder=import_string(settings.SELECT2_JSON_ENCODER), ) def get_queryset(self): """Get QuerySet from cached widget.""" kwargs = { model_field_name: self.request.GET.get(form_field_name) for form_field_name, model_field_name in self.widget.dependent_fields.items() } kwargs.update( { f"{model_field_name}__in": self.request.GET.getlist( f"{form_field_name}[]", [] ) for form_field_name, model_field_name in self.widget.dependent_fields.items() } ) return self.widget.filter_queryset( self.request, self.term, self.queryset, **{k: v for k, v in kwargs.items() if v}, ) def get_paginate_by(self, queryset): """Paginate response by size of widget's `max_results` parameter.""" return self.widget.max_results def get_widget_or_404(self): """ Get and return widget from cache. Raises: Http404: If if the widget can not be found or no id is provided. Returns: ModelSelect2Mixin: Widget from cache. """ field_id = self.kwargs.get("field_id", self.request.GET.get("field_id", None)) if not field_id: raise Http404('No "field_id" provided.') try: key = signing.loads(field_id) except BadSignature: raise Http404('Invalid "field_id".') else: cache_key = f"{settings.SELECT2_CACHE_PREFIX}{key}" widget_dict = cache.get(cache_key) if widget_dict is None: raise Http404("field_id not found") if widget_dict.pop("url") != self.request.path: raise Http404("field_id was issued for the view.") qs, qs.query = widget_dict.pop("queryset") self.queryset = qs.all() widget_dict["queryset"] = self.queryset widget_cls = widget_dict.pop("cls") return widget_cls(**widget_dict) ``` -------------------------------- ### Configure Django-Select2 Options via Django Widget Attributes Source: https://django-select2.readthedocs.io/en/latest/django_select2 Provides an example of configuring Select2 widget options using `data-*` attributes within the Django form definition. These attributes are passed to the widget's `attrs` dictionary and are automatically picked up by Select2 for initialization, such as setting minimum input length and placeholder. ```python class MyForm(forms.Form): my_field = forms.ModelMultipleChoiceField( widget=ModelSelect2MultipleWidget( model=MyModel search_fields=['another_field'] attrs={ "data-minimum-input-length": 0, "data-placeholder": "Select an option", "data-close-on-select": "false", } ) ) ``` -------------------------------- ### Configure Django-Select2 Cache Backend Source: https://django-select2.readthedocs.io/en/latest/django_select2 Sets the cache backend for Django-Select2 to ensure consistent state across multiple machines. Requires a cache backend like Redis or Memcached configured in settings.py. The example shows how to set up a default cache and a specific 'select2' cache using django-redis. ```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' ``` -------------------------------- ### Django-Select2: ModelSelect2Mixin Search Fields Example Source: https://django-select2.readthedocs.io/en/latest/django_select2 Shows how to define 'search_fields' within the ModelSelect2Mixin for filtering QuerySets. This is crucial for implementing searchable dropdowns based on model attributes. ```python class ModelSelect2Mixin(object): # ... other methods ... search_fields = [] # Example: # search_fields = [ # 'title__icontains', # ] ``` -------------------------------- ### Custom ModelSelect2TagWidget Implementation in Django Source: https://django-select2.readthedocs.io/en/latest/django_select2 Example of extending `ModelSelect2TagWidget` to implement `value_from_datadict`. This custom method handles the creation of new objects based on user input when tags are added and ensures primary keys are correctly returned. It requires defining the `queryset` and assumes the `MyModel` has a 'title' field for 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 ``` -------------------------------- ### Customize Django-Select2 JavaScript Files Source: https://django-select2.readthedocs.io/en/latest/_modules/django_select2/conf This code example illustrates how to customize the JavaScript files used by Django-Select2. You can specify a different path to the Select2 JS file or disable loading any JS by providing an empty list. This is useful for serving Select2 from local static resources or using a specific version. ```python # Use a custom path for the Select2 JS file SELECT2_JS = ['assets/js/select2.min.js'] # Disable loading any Select2 JS files SELECT2_JS = [] ``` -------------------------------- ### Select2 Tag Widget with Dynamic Option Creation Source: https://django-select2.readthedocs.io/en/latest/_modules/django_select2/forms The `Select2TagWidget` class combines `Select2TagMixin`, `Select2Mixin`, and `forms.SelectMultiple` to create a widget that supports Select2's tagging functionality. It allows users to dynamically create new options by typing in the input field. The example demonstrates custom `value_from_datadict` and `optgroups` methods for handling comma-separated values, suitable for Django's `ArrayField`. ```python class Select2TagWidget(Select2TagMixin, Select2Mixin, forms.SelectMultiple): """ Select2 drop in widget with tagging support. It allows to dynamically create new options from text input by the user. Example for :class:`.django.contrib.postgres.fields.ArrayField`:: class MyWidget(Select2TagWidget): 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)] """ ``` -------------------------------- ### Add Book Create View to URLs Source: https://django-select2.readthedocs.io/en/latest/index Maps the BookCreateView to the '/book/create' URL path in the Django project's urls.py. ```python # urls.py 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"), ] ``` -------------------------------- ### Customizing Instance Label in Django Select2 Widget Source: https://django-select2.readthedocs.io/en/latest/_modules/django_select2/forms This Python method, `label_from_instance`, is part of a Django Select2 widget. It allows developers to customize how each model instance is represented as a label in the select options. By overriding this method, you can format the display text, for example, by converting it to uppercase as shown in the example. ```python def label_from_instance(self, obj): """ Return option label representation from instance. Can be overridden to change the representation of each choice. Example usage:: class MyWidget(ModelSelect2Widget): def label_from_instance(obj): return str(obj.title).upper() Args: obj (django.db.models.Model): Instance of Django Model. Returns: str: Option label. """ return str(obj) ``` -------------------------------- ### GET /api/field-data (AutoResponseView) Source: https://django-select2.readthedocs.io/en/latest/_modules/django_select2/views Handles HTTP GET requests from django-select2 heavy model widgets. Returns a JSON response containing paginated results from a filtered queryset, with each result rendered using the widget's result_from_instance method. Supports dependent fields filtering and custom pagination. ```APIDOC ## GET /api/field-data ### Description Returns paginated JSON results for Select2 heavy model widgets. Each result is rendered by the widget's ModelSelect2Mixin.result_from_instance method. Supports filtering via dependent fields and search terms. ### Method GET ### Endpoint /api/field-data ### Parameters #### Query Parameters - **field_id** (string) - Required - Signed widget identifier used to retrieve widget configuration from cache - **term** (string) - Optional - Search term for filtering queryset results - **page** (integer) - Optional - Page number for pagination (default: 1) - **{form_field_name}** (string) - Optional - Dependent field filter values - **{form_field_name}[]** (array) - Optional - Multiple dependent field filter values ### Request Example ``` GET /api/field-data?field_id=abc123def456&term=foo&page=1 ``` ### Response #### Success Response (200 OK) - **results** (array) - List of paginated result objects - **id** (mixed) - Unique identifier for the result item - **text** (string) - Display text for the result item - **more** (boolean) - Indicates if additional pages of results are available #### Response Example ```json { "results": [ { "id": 123, "text": "foo" }, { "id": 124, "text": "foobar" } ], "more": true } ``` #### Error Response (404 Not Found) - Returned when field_id is missing, invalid, or not found in cache - Returned when field_id was issued for a different view URL ### Implementation Details - **View Class**: AutoResponseView (extends BaseListView) - **Supported Methods**: GET only - **Response Format**: JSON (via JsonResponse with configurable encoder from SELECT2_JSON_ENCODER setting) - **Pagination**: Automatically paginated by widget's max_results parameter - **Widget Caching**: Widget configuration retrieved from cache using signed field_id - **Dependent Fields**: Supports filtering by dependent form field values ``` -------------------------------- ### Add Book Creation View to Django URLs Source: https://django-select2.readthedocs.io/en/latest/_sources/index Configuration snippet for Django's URL configuration (urls.py) to map a URL path to the BookCreateView. Includes the django_select2 URLs as well. ```python # urls.py 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"), ] ``` -------------------------------- ### URLs Module Source: https://django-select2.readthedocs.io/en/latest/_sources/django_select2 The django_select2.urls module handles URL configuration and routing for Select2 API endpoints. Provides URL patterns for data retrieval and widget initialization. ```APIDOC ## URLs Module ### Module django_select2.urls ### Description Handles URL configuration and routing for Django Select2 API endpoints. Includes URL patterns for accessing Select2 data and widget functionality. ### Usage ```python from django.urls import path, include urlpatterns = [ path('select2/', include('django_select2.urls')), ] ``` ``` -------------------------------- ### Add django_select2 to INSTALLED_APPS Source: https://django-select2.readthedocs.io/en/latest/_sources/index Configuration snippet for Django's settings.py to include 'django_select2' in INSTALLED_APPS. Ensures Django's admin app is also enabled for compatibility. ```python INSTALLED_APPS = [ # other django apps… 'django.contrib.admin', # other 3rd party apps… 'django_select2', ] ``` -------------------------------- ### URL Configuration for Django-Select2 Source: https://django-select2.readthedocs.io/en/latest/django_select2 Instructions on how to include Django-Select2's URL patterns in your project's main URL configuration. ```APIDOC ## Include Django-Select2 URLs ### Description Add the Django-Select2 URL configuration to your project's `urls.py` file to enable its views, particularly for model widgets. ### Method N/A (This is a URL configuration instruction) ### Endpoint N/A (This is a URL configuration instruction) ### Parameters N/A (This is a URL configuration instruction) ### Request Example ```python # urls.py from django.urls import path, include urlpatterns = [ # ... other url patterns path('select2/', include('django_select2.urls')), ] ``` ### Response N/A (This is a URL configuration instruction) ``` -------------------------------- ### Django Template for Book Creation Form Source: https://django-select2.readthedocs.io/en/latest/_sources/index Basic HTML template for rendering the BookForm. Includes form media for CSS and JS, and uses {{ form.as_p }} to display form fields. ```html