Skip to content

Commit

Permalink
Add Select2 mixin that uses Django's own select template
Browse files Browse the repository at this point in the history
  • Loading branch information
codingjoe committed Feb 3, 2022
1 parent b858953 commit 6e7e458
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
2 changes: 1 addition & 1 deletion django_select2/__init__.py
Expand Up @@ -9,5 +9,5 @@
"""
from django import get_version

if get_version() < '3.2':
if get_version() < "3.2":
default_app_config = "django_select2.apps.Select2AppConfig"
29 changes: 24 additions & 5 deletions django_select2/forms.py
Expand Up @@ -54,7 +54,7 @@

import django
from django import forms
from django.contrib.admin.widgets import SELECT2_TRANSLATIONS
from django.contrib.admin.widgets import SELECT2_TRANSLATIONS, AutocompleteMixin
from django.core import signing
from django.db.models import Q
from django.forms.models import ModelChoiceIterator
Expand All @@ -65,7 +65,9 @@
from .conf import settings

if django.VERSION < (4, 0):
from django.contrib.admin.utils import lookup_needs_distinct as lookup_spawns_duplicates
from django.contrib.admin.utils import (
lookup_needs_distinct as lookup_spawns_duplicates,
)
else:
from django.contrib.admin.utils import lookup_spawns_duplicates

Expand All @@ -79,6 +81,9 @@ class Select2Mixin:
form media.
"""

css_class_name = "django-select2"
theme = None

empty_label = ""

def __init__(self, *args, **kwargs):
Expand All @@ -90,7 +95,7 @@ def build_attrs(self, base_attrs, extra_attrs=None):
default_attrs = {
"lang": self.i18n_name,
"data-minimum-input-length": 0,
"data-theme": settings.SELECT2_THEME,
"data-theme": self.theme or settings.SELECT2_THEME,
}
if self.is_required:
default_attrs["data-allow-clear"] = "false"
Expand All @@ -102,9 +107,9 @@ def build_attrs(self, base_attrs, extra_attrs=None):
attrs = super().build_attrs(default_attrs, extra_attrs=extra_attrs)

if "class" in attrs:
attrs["class"] += " django-select2"
attrs["class"] += " " + self.css_class_name
else:
attrs["class"] = "django-select2"
attrs["class"] = self.css_class_name
return attrs

def optgroups(self, name, value, attrs=None):
Expand Down Expand Up @@ -137,6 +142,20 @@ def media(self):
)


class Select2AdminMixin:
"""Select2 mixin that uses Django's own select template."""

css_class_name = "admin-autocomplete"
theme = "admin-autocomplete"

@property
def media(self):
return forms.Media(
js=Select2Mixin().media._js,
css=AutocompleteMixin(None, None).media._css,
)


class Select2TagMixin:
"""Mixin to add select2 tag functionality."""

Expand Down
18 changes: 18 additions & 0 deletions tests/test_forms.py
Expand Up @@ -21,6 +21,7 @@
ModelSelect2TagWidget,
ModelSelect2Widget,
Select2Widget,
Select2AdminMixin,
)
from tests.testapp import forms
from tests.testapp.forms import (
Expand Down Expand Up @@ -175,6 +176,23 @@ def test_theme_setting(self, settings):
assert 'data-theme="classic"' in widget.render("name", None)


class TestSelect2AdminMixin:
def test_media(self):
translation.activate("en")
assert tuple(Select2AdminMixin().media._js) == (
f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js",
f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/i18n/en.js",
"django_select2/django_select2.js",
)

assert dict(Select2AdminMixin().media._css) == {
"screen": [
"admin/css/vendor/select2/select2.min.css",
"admin/css/autocomplete.css",
]
}


class TestSelect2MixinSettings:
def test_default_media(self):
sut = Select2Widget()
Expand Down

0 comments on commit 6e7e458

Please sign in to comment.