Skip to content

Commit

Permalink
Change default Select2 version to Django's vendored version
Browse files Browse the repository at this point in the history
  • Loading branch information
codingjoe committed Nov 5, 2022
1 parent 3781b67 commit 112846c
Show file tree
Hide file tree
Showing 12 changed files with 56 additions and 112 deletions.
75 changes: 9 additions & 66 deletions django_select2/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@

__all__ = ("settings", "Select2Conf")

from django.contrib.admin.widgets import SELECT2_TRANSLATIONS


class Select2Conf(AppConf):
"""Settings for Django-Select2."""

LIB_VERSION = "4.0.12"
"""Version of the Select2 library."""

CACHE_BACKEND = "default"
"""
Django-Select2 uses Django's cache to sure a consistent state across multiple machines.
Expand Down Expand Up @@ -56,11 +55,9 @@ class Select2Conf(AppConf):
It has set `select2_` as a default value, which you can change if needed.
"""

JS = "https://cdnjs.cloudflare.com/ajax/libs/select2/{version}/js/select2.min.js".format(
version=LIB_VERSION
)
JS = "admin/js/vendor/select2/select2.full.min.js"
"""
The URI for the Select2 JS file. By default this points to the Cloudflare CDN.
The URI for the Select2 JS file. By default this points to version shipped with Django.
If you want to select the version of the JS library used, or want to serve it from
the local 'static' resources, add a line to your settings.py like so::
Expand All @@ -76,11 +73,9 @@ class Select2Conf(AppConf):
develop without an Internet connection.
"""

CSS = "https://cdnjs.cloudflare.com/ajax/libs/select2/{version}/css/select2.min.css".format(
version=LIB_VERSION
)
CSS = "admin/css/vendor/select2/select2.min.css"
"""
The URI for the Select2 CSS file. By default this points to the Cloudflare CDN.
The URI for the Select2 CSS file. By default this points to version shipped with Django.
If you want to select the version of the library used, or want to serve it from
the local 'static' resources, add a line to your settings.py like so::
Expand Down Expand Up @@ -112,13 +107,9 @@ class Select2Conf(AppConf):
.. tip:: When using other themes, you may need use select2 css and theme css.
"""

I18N_PATH = (
"https://cdnjs.cloudflare.com/ajax/libs/select2/{version}/js/i18n".format(
version=LIB_VERSION
)
)
I18N_PATH = "admin/js/vendor/select2/i18n"
"""
The base URI for the Select2 i18n files. By default this points to the Cloudflare CDN.
The base URI for the Select2 i18n files. By default this points to version shipped with Django.
If you want to select the version of the I18N library used, or want to serve it from
the local 'static' resources, add a line to your settings.py like so::
Expand All @@ -129,55 +120,7 @@ class Select2Conf(AppConf):
develop without an Internet connection.
"""

I18N_AVAILABLE_LANGUAGES = [
"ar",
"az",
"bg",
"ca",
"cs",
"da",
"de",
"el",
"en",
"es",
"et",
"eu",
"fa",
"fi",
"fr",
"gl",
"he",
"hi",
"hr",
"hu",
"id",
"is",
"it",
"ja",
"km",
"ko",
"lt",
"lv",
"mk",
"ms",
"nb",
"nl",
"pl",
"pt-BR",
"pt",
"ro",
"ru",
"sk",
"sr-Cyrl",
"sr",
"sv",
"th",
"tr",
"uk",
"vi",
"zh-CN",
"zh-TW",
]
I18N_AVAILABLE_LANGUAGES = list(SELECT2_TRANSLATIONS.values())
"""
List of available translations.
Expand Down
4 changes: 2 additions & 2 deletions django_select2/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
have to be pre-rendered onto the page
and JavaScript would be used to search
through them. Said that, they are also one
the most easiest to use. They are a
the easiest to use. They are a
drop-in-replacement for Django's default
select widgets.
Expand Down Expand Up @@ -293,7 +293,7 @@ def render(self, *args, **kwargs):
return output

def _get_cache_key(self):
return "%s%s" % (settings.SELECT2_CACHE_PREFIX, self.uuid)
return f"{settings.SELECT2_CACHE_PREFIX}{self.uuid}"

def set_to_cache(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion django_select2/static/django_select2/django_select2.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
module.exports = factory(require('jquery'))
} else {
// Browser globals
factory(jQuery)
factory(jQuery || window.django.jQuery)
}
}(function ($) {
'use strict'
Expand Down
2 changes: 1 addition & 1 deletion django_select2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def get_widget_or_404(self):
except BadSignature:
raise Http404('Invalid "field_id".')
else:
cache_key = "%s%s" % (settings.SELECT2_CACHE_PREFIX, key)
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")
Expand Down
8 changes: 4 additions & 4 deletions docs/extra.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ the field in the form. The value represents the name of the field in the model (
class AddressForm(forms.Form):
country = forms.ModelChoiceField(
queryset=Country.objects.all(),
label=u"Country",
label="Country",
widget=ModelSelect2Widget(
model=Country,
search_fields=['name__icontains'],
Expand All @@ -48,7 +48,7 @@ the field in the form. The value represents the name of the field in the model (
city = forms.ModelChoiceField(
queryset=City.objects.all(),
label=u"City",
label="City",
widget=ModelSelect2Widget(
model=City,
search_fields=['name__icontains'],
Expand All @@ -72,7 +72,7 @@ Customize the form in a manner:
class AddressForm(forms.Form):
country = forms.ModelChoiceField(
queryset=Country.objects.all(),
label=u"Country",
label="Country",
widget=ModelSelect2Widget(
search_fields=['name__icontains'],
dependent_fields={'city': 'cities'},
Expand All @@ -81,7 +81,7 @@ Customize the form in a manner:
city = forms.ModelChoiceField(
queryset=City.objects.all(),
label=u"City",
label="City",
widget=ModelSelect2Widget(
search_fields=['name__icontains'],
dependent_fields={'country': 'country'},
Expand Down
18 changes: 14 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ Install ``django-select2``::
python3 -m pip install django-select2

Add ``django_select2`` to your ``INSTALLED_APPS`` in your project settings.
Since version 8, please ensure that Django's admin app is enabled too:

.. code-block:: python
INSTALLED_APPS = [
# other django apps…
'django.contrib.admin',
# other 3rd party apps…
'django_select2',
]
Add ``django_select`` to your URL root configuration:

Expand All @@ -16,20 +26,20 @@ Add ``django_select`` to your URL root configuration:
from django.urls import include, path
urlpatterns = [
# other patterns
# other patterns
path("select2/", include("django_select2.urls")),
# other patterns
# other patterns
]
``django-select2`` requires a cache backend which is **persistent**
across all application servers..
across all application servers..

**This means that the** :class:`.DummyCache` **backend will not work!**

The default cache backend is :class:`.LocMemCache`, which is persistent
across a single node. For projects with a single application server
this will work fine, however you will run into issues when
this will work fine, however you will run into issues when
you scale up into multiple servers.

Below is an example setup using Redis, which is a solution that
Expand Down
6 changes: 2 additions & 4 deletions example/example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,12 @@

CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"BACKEND": "django.core.cache.backends.redis.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
},
"select2": {
"BACKEND": "django_redis.cache.RedisCache",
"BACKEND": "django.core.cache.backends.redis.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/2",
"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
},
}

Expand Down
4 changes: 2 additions & 2 deletions example/example/templates/example/book_form.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
{% load static %}<!DOCTYPE html>
<html lang="en">
<head>
<title>Create Book</title>
Expand All @@ -14,7 +14,7 @@ <h1>Create a new Book</h1>
{{ form.as_p }}
<input type="submit">
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="{% static 'admin/js/vendor/jquery/jquery.min.js' %}"></script>
{{ form.media.js }}
</body>
</html>
2 changes: 1 addition & 1 deletion example/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
-e ..
django-redis
redis
39 changes: 16 additions & 23 deletions tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from selenium.webdriver.support.wait import WebDriverWait

from django_select2.cache import cache
from django_select2.conf import settings
from django_select2.forms import (
HeavySelect2MultipleWidget,
HeavySelect2Widget,
Expand Down Expand Up @@ -135,44 +134,44 @@ def test_empty_option(self, db):
def test_i18n(self):
translation.activate("de")
assert tuple(Select2Widget().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/de.js",
"admin/js/vendor/select2/select2.full.min.js",
"admin/js/vendor/select2/i18n/de.js",
"django_select2/django_select2.js",
)

translation.activate("en")
assert tuple(Select2Widget().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",
"admin/js/vendor/select2/select2.full.min.js",
"admin/js/vendor/select2/i18n/en.js",
"django_select2/django_select2.js",
)

translation.activate("00")
assert tuple(Select2Widget().media._js) == (
f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js",
"admin/js/vendor/select2/select2.full.min.js",
"django_select2/django_select2.js",
)

translation.activate("sr-cyrl")
translation.activate("sr-Cyrl")
assert tuple(Select2Widget().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/sr-Cyrl.js",
"admin/js/vendor/select2/select2.full.min.js",
"admin/js/vendor/select2/i18n/sr-Cyrl.js",
"django_select2/django_select2.js",
)

pytest.importorskip("django", minversion="2.0.4")

translation.activate("zh-hans")
assert tuple(Select2Widget().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/zh-CN.js",
"admin/js/vendor/select2/select2.full.min.js",
"admin/js/vendor/select2/i18n/zh-CN.js",
"django_select2/django_select2.js",
)

translation.activate("zh-hant")
assert tuple(Select2Widget().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/zh-TW.js",
"admin/js/vendor/select2/select2.full.min.js",
"admin/js/vendor/select2/i18n/zh-TW.js",
"django_select2/django_select2.js",
)

Expand All @@ -186,8 +185,8 @@ 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",
"admin/js/vendor/select2/select2.full.min.js",
"admin/js/vendor/select2/i18n/en.js",
"django_select2/django_select2.js",
)

Expand All @@ -204,14 +203,8 @@ class TestSelect2MixinSettings:
def test_default_media(self):
sut = Select2Widget()
result = sut.media.render()
assert (
f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/js/select2.min.js"
in result
)
assert (
f"https://cdnjs.cloudflare.com/ajax/libs/select2/{settings.SELECT2_LIB_VERSION}/css/select2.min.css"
in result
)
assert "admin/js/vendor/select2/select2.full.min.js" in result
assert "admin/css/vendor/select2/select2.min.css" in result
assert "django_select2/django_select2.js" in result

def test_js_setting(self, settings):
Expand Down
1 change: 1 addition & 0 deletions tests/testapp/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.staticfiles",
"django.contrib.admin",
"django_select2",
"tests.testapp",
)
Expand Down
7 changes: 3 additions & 4 deletions tests/testapp/templates/form.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{% load static %}
<!DOCTYPE html>
<html>
{% load static %}<!DOCTYPE html>
<html lang="en">
<head>
{{ form.media.css }}
<style type="text/css">
Expand All @@ -15,7 +14,7 @@
{{ form }}
<input type="submit" value="Submit Form"/>
</form>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="{% static 'admin/js/vendor/jquery/jquery.min.js' %}"></script>
<script type="text/javascript">
window.onerror = function (msg) {
$("body").attr("JSError", msg);
Expand Down

0 comments on commit 112846c

Please sign in to comment.