From d27760e4e2b58b929aa9dad98d4c954c4c558e6e Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Sun, 24 May 2020 18:10:58 +0200 Subject: [PATCH 001/165] Fix NPM release version --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3a25ac0e..2a425c4f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,6 +24,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v1 + - uses: actions/setup-python@v1 + - run: python set_version.py - uses: actions/checkout@v2 - name: Upload packages run: npm publish From 35354d0f9fcc19725f61e15c5d6fc65a24ff3615 Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Sun, 24 May 2020 18:27:00 +0200 Subject: [PATCH 002/165] Fix NPM release command --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2a425c4f..699b3186 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,8 +25,8 @@ jobs: steps: - uses: actions/setup-node@v1 - uses: actions/setup-python@v1 - - run: python set_version.py - uses: actions/checkout@v2 + - run: python set_version.py - name: Upload packages run: npm publish env: From b9d02bc5bc1e4c284277b28b1ecb5f3763f5b972 Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Thu, 28 May 2020 12:09:18 +0200 Subject: [PATCH 003/165] Fix code block syntax, thx @hartwork --- docs/index.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index c27598a6..6f8b0d26 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,9 +3,7 @@ Installation ------------ -Install ``django-select2`` - -.. code-block:: python +Install ``django-select2``:: python3 -m pip install django-select2 From 5356c7cafa2503260d48a23e1bb1db8cb59b17dd Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 8 Sep 2020 08:01:48 -0400 Subject: [PATCH 004/165] Clarify the key-value pair for the dependent_fields docs. --- docs/extra.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/extra.rst b/docs/extra.rst index 664fe202..c3524ce7 100644 --- a/docs/extra.rst +++ b/docs/extra.rst @@ -27,10 +27,11 @@ Here are our two models: Customizing a Form `````````````````` -Lets link two widgets via *dependent_fields*. +Lets link two widgets via a *dependent_fields* dictionary. The key represents the name of +the field in the form. The value represents the name of the field in the model (used in `queryset`). .. code-block:: python - :emphasize-lines: 15 + :emphasize-lines: 17 class AddressForm(forms.Form): country = forms.ModelChoiceField( From f5a9d48d8c5e99258e5ff72f6d531da45e45c17a Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 15 Dec 2020 11:02:55 +0100 Subject: [PATCH 005/165] Fix black code style --- .fussyfox.yml | 1 + .github/workflows/ci.yml | 9 --------- django_select2/conf.py | 6 ++++-- tests/test_forms.py | 31 ++++++++++++++++++------------- tests/testapp/forms.py | 6 ++++-- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/.fussyfox.yml b/.fussyfox.yml index 600df195..6a17e6bd 100644 --- a/.fussyfox.yml +++ b/.fussyfox.yml @@ -1,4 +1,5 @@ - bandit +- black - flake8 - isort - pydocstyle diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf58dc22..de7a51fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,14 +7,6 @@ on: jobs: - black: - runs-on: ubuntu-latest - steps: - - uses: actions/setup-python@v2 - - uses: actions/checkout@v2 - - run: python -m pip install black - - run: black --check --diff . - dist: runs-on: ubuntu-latest steps: @@ -46,7 +38,6 @@ jobs: pytest: needs: - standardjs - - black strategy: matrix: python-version: diff --git a/django_select2/conf.py b/django_select2/conf.py index 3896fb62..4d686005 100644 --- a/django_select2/conf.py +++ b/django_select2/conf.py @@ -96,8 +96,10 @@ class Select2Conf(AppConf): develop without an Internet connection. """ - I18N_PATH = "https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bversion%7D/js/i18n".format( - version=LIB_VERSION + I18N_PATH = ( + "https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bversion%7D/js/i18n".format( + version=LIB_VERSION + ) ) """ The base URI for the Select2 i18n files. By default this points to the Cloudflare CDN. diff --git a/tests/test_forms.py b/tests/test_forms.py index 89ef8b69..1f02c828 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -222,26 +222,29 @@ def test_initial_form_class(self): def test_selected_option(self, db): not_required_field = self.form.fields["primary_genre"] assert not_required_field.required is False - assert '' in not_required_field.widget.render( - "primary_genre", 1 - ) or '' in not_required_field.widget.render( - "primary_genre", 1 - ), not_required_field.widget.render( - "primary_genre", 1 - ) + assert ( + '' + in not_required_field.widget.render("primary_genre", 1) + or '' + in not_required_field.widget.render("primary_genre", 1) + ), (not_required_field.widget.render("primary_genre", 1)) def test_many_selected_option(self, db, genres): field = HeavySelect2MultipleWidgetForm().fields["genres"] field.widget.choices = NUMBER_CHOICES widget_output = field.widget.render("genres", [1, 2]) - selected_option = ''.format( - pk=1, value="One" + selected_option = ( + ''.format( + pk=1, value="One" + ) ) selected_option_a = ''.format( pk=1, value="One" ) - selected_option2 = ''.format( - pk=2, value="Two" + selected_option2 = ( + ''.format( + pk=2, value="Two" + ) ) selected_option2a = ''.format( pk=2, value="Two" @@ -334,8 +337,10 @@ def test_selected_option(self, db, genres): not_required_field = self.form.fields["primary_genre"] assert not_required_field.required is False widget_output = not_required_field.widget.render("primary_genre", genre.pk) - selected_option = ''.format( - pk=genre.pk, value=force_str(genre) + selected_option = ( + ''.format( + pk=genre.pk, value=force_str(genre) + ) ) selected_option_a = ''.format( pk=genre.pk, value=force_str(genre) diff --git a/tests/testapp/forms.py b/tests/testapp/forms.py index 5fa245d9..da9487c5 100644 --- a/tests/testapp/forms.py +++ b/tests/testapp/forms.py @@ -111,7 +111,8 @@ class ArtistModelSelect2MultipleWidgetForm(forms.Form): title = forms.CharField(max_length=50) genres = forms.ModelMultipleChoiceField( widget=ModelSelect2MultipleWidget( - queryset=models.Genre.objects.all(), search_fields=["title__icontains"], + queryset=models.Genre.objects.all(), + search_fields=["title__icontains"], ), queryset=models.Genre.objects.all(), required=True, @@ -119,7 +120,8 @@ class ArtistModelSelect2MultipleWidgetForm(forms.Form): featured_artists = forms.ModelMultipleChoiceField( widget=ModelSelect2MultipleWidget( - queryset=models.Artist.objects.all(), search_fields=["title__icontains"], + queryset=models.Artist.objects.all(), + search_fields=["title__icontains"], ), queryset=models.Artist.objects.all(), required=False, From 4e7bbad45347653b6bb713ec41fcdb6aa896616d Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 15 Dec 2020 11:26:26 +0100 Subject: [PATCH 006/165] Fix docs build --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de7a51fb..3ced4594 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-python@v2 + - run: python -m pip install -U setuptools wheel - uses: actions/checkout@v2 - run: sudo apt-get install -y gettext graphviz - run: python setup.py develop From 98c9c45def8989c0d0fea19e8d58bacb90a98225 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 15 Dec 2020 11:58:33 +0100 Subject: [PATCH 007/165] Fix bandit config --- .bandit | 2 +- example/example/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bandit b/.bandit index fba0d25d..b7df1762 100644 --- a/.bandit +++ b/.bandit @@ -1,2 +1,2 @@ [bandit] -exclude: tests +exclude: ./tests diff --git a/example/example/settings.py b/example/example/settings.py index 83067236..7e629a6e 100644 --- a/example/example/settings.py +++ b/example/example/settings.py @@ -20,7 +20,7 @@ # See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = "kstexlapcf3lucx@47mmxsu9-9eixia+6n97aw)4$qo&!laxad" +SECRET_KEY = "kstexlapcf3lucx@47mmxsu9-9eixia+6n97aw)4$qo&!laxad" # nosec # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True From 6ad44479d3aeba7bae4d9b5d069598fb705222b1 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 15 Dec 2020 11:59:31 +0100 Subject: [PATCH 008/165] Add Python 3.9 support --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ced4594..913ff011 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,7 @@ jobs: - "3.6" - "3.7" - "3.8" + - "3.9" django-version: - "2.2" - "3.0" From 15629f4bb5b705465e2e5d4118d4d91afb0dcea0 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 15 Dec 2020 11:59:44 +0100 Subject: [PATCH 009/165] Remove official Python 3.6 support --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 913ff011..144fecc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,6 @@ jobs: strategy: matrix: python-version: - - "3.6" - "3.7" - "3.8" - "3.9" From 0e1b8c4671721d48fe13fb438150c810ba97f3f5 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 15 Dec 2020 12:00:07 +0100 Subject: [PATCH 010/165] Add official Django 3.1 support --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 144fecc3..5e8cdf0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,7 @@ jobs: django-version: - "2.2" - "3.0" + - "3.1" runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} From 9cb9848dfe5faacef9077f2a0efd1ca97bc2fd0a Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 15 Dec 2020 12:02:32 +0100 Subject: [PATCH 011/165] Remove official Django 3.0 support --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e8cdf0e..bf69a668 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,6 @@ jobs: - "3.9" django-version: - "2.2" - - "3.0" - "3.1" runs-on: ubuntu-latest steps: From 709ec195504a0028ca053845d6e62886e7198f01 Mon Sep 17 00:00:00 2001 From: Jan Pieter Waagmeester Date: Mon, 26 Oct 2020 15:58:21 +0100 Subject: [PATCH 012/165] Remove colon in example for use with ArrayField --- django_select2/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index 1f5554b9..0fedc39d 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -178,7 +178,7 @@ class Select2TagWidget(Select2TagMixin, Select2Mixin, forms.SelectMultiple): class MyWidget(Select2TagWidget): def value_from_datadict(self, data, files, name): - values = super().value_from_datadict(data, files, name): + values = super().value_from_datadict(data, files, name) return ",".join(values) def optgroups(self, name, value, attrs=None): From 07054b2d8ff15144c6b1b00577f3c898d47712bc Mon Sep 17 00:00:00 2001 From: David Bramwell Date: Tue, 5 Jan 2021 11:36:35 +0000 Subject: [PATCH 013/165] Split search terms only for __contains queries Split search terms only for `__contains` queries and not for `__startswith` or `__endswith`. We no also split not only be whitespace but tab and newline. If multiple search fields are defined conditions combined with and OR. If single word matches in a for contains queries are OR combined as well. Co-Authored-By: codingjoe --- django_select2/forms.py | 21 +++++++++++-------- tests/test_forms.py | 46 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index 0fedc39d..32d4ba11 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -46,8 +46,8 @@ :parts: 1 """ +import re import uuid -from functools import reduce from itertools import chain from pickle import PicklingError # nosec @@ -315,6 +315,8 @@ class HeavySelect2TagWidget(HeavySelect2Mixin, Select2TagWidget): class ModelSelect2Mixin: """Widget mixin that provides attributes and methods for :class:`.AutoResponseView`.""" + _word_split_pattern = re.compile(r"\t|\n| ") + model = None queryset = None search_fields = [] @@ -397,14 +399,15 @@ def filter_queryset(self, request, term, queryset=None, **dependent_fields): queryset = self.get_queryset() search_fields = self.get_search_fields() select = Q() - term = term.replace("\t", " ") - term = term.replace("\n", " ") - for t in [t for t in term.split(" ") if not t == ""]: - select &= reduce( - lambda x, y: x | Q(**{y: t}), - search_fields[1:], - Q(**{search_fields[0]: t}), - ) + + for field in search_fields: + field_select = Q(**{field: term}) + if "contains" in field: + for word in filter(None, self._word_split_pattern.split(term)): + field_select |= Q(**{field: word}) + + select |= field_select + if dependent_fields: select &= Q(**dependent_fields) diff --git a/tests/test_forms.py b/tests/test_forms.py index 1f02c828..130f650c 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -446,6 +446,52 @@ def test_filter_queryset(self, genres): ) assert qs.exists() + def test_filter_queryset__startswith(self, genres): + genre = Genre.objects.create(title="Space Genre") + widget = TitleModelSelect2Widget(queryset=Genre.objects.all()) + assert widget.filter_queryset(None, genre.title).exists() + + widget = TitleModelSelect2Widget( + search_fields=["title__istartswith"], queryset=Genre.objects.all() + ) + qs = widget.filter_queryset(None, "Space Gen") + assert qs.exists() + + qs = widget.filter_queryset(None, "Gen") + assert not qs.exists() + + def test_filter_queryset__contains(self, genres): + genre = Genre.objects.create(title="Space Genre") + widget = TitleModelSelect2Widget(queryset=Genre.objects.all()) + assert widget.filter_queryset(None, genre.title).exists() + + widget = TitleModelSelect2Widget( + search_fields=["title__contains"], queryset=Genre.objects.all() + ) + qs = widget.filter_queryset(None, "Space Gen") + assert qs.exists() + + qs = widget.filter_queryset(None, "NOT Gen") + assert qs.exists(), "contains works even if only one part matches" + + def test_filter_queryset__multiple_fields(self, genres): + genre = Genre.objects.create(title="Space Genre") + widget = TitleModelSelect2Widget(queryset=Genre.objects.all()) + assert widget.filter_queryset(None, genre.title).exists() + + widget = TitleModelSelect2Widget( + search_fields=[ + "title__startswith", + "title__endswith", + ], + queryset=Genre.objects.all(), + ) + qs = widget.filter_queryset(None, "Space") + assert qs.exists() + + qs = widget.filter_queryset(None, "Genre") + assert qs.exists() + def test_model_kwarg(self): widget = ModelSelect2Widget(model=Genre, search_fields=["title__icontains"]) genre = Genre.objects.last() From e735be2016f0a2349f0f8acd51eb6b51741cc123 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 16 Jan 2021 16:34:41 +0100 Subject: [PATCH 014/165] Fix #29 -- Do not filter based on empty search term --- django_select2/forms.py | 15 ++++++++------- tests/test_forms.py | 10 ++++++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index 32d4ba11..76fc525a 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -400,13 +400,14 @@ def filter_queryset(self, request, term, queryset=None, **dependent_fields): search_fields = self.get_search_fields() select = Q() - for field in search_fields: - field_select = Q(**{field: term}) - if "contains" in field: - for word in filter(None, self._word_split_pattern.split(term)): - field_select |= Q(**{field: word}) - - select |= field_select + if term != "": + for field in search_fields: + field_select = Q(**{field: term}) + if "contains" in field: + for word in filter(None, self._word_split_pattern.split(term)): + field_select |= Q(**{field: word}) + + select |= field_select if dependent_fields: select &= Q(**dependent_fields) diff --git a/tests/test_forms.py b/tests/test_forms.py index 130f650c..85b9265a 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -446,6 +446,16 @@ def test_filter_queryset(self, genres): ) assert qs.exists() + def test_filter_queryset__empty(self, genres): + widget = TitleModelSelect2Widget(queryset=Genre.objects.all()) + assert widget.filter_queryset(None, genres[0].title[:3]).exists() + + widget = TitleModelSelect2Widget( + search_fields=["title__icontains"], queryset=Genre.objects.all() + ) + qs = widget.filter_queryset(None, "") + assert qs.exists() + def test_filter_queryset__startswith(self, genres): genre = Genre.objects.create(title="Space Genre") widget = TitleModelSelect2Widget(queryset=Genre.objects.all()) From bc6282fa2f404d1557e9db7d5db6ea37c9cdb9ac Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 6 Mar 2021 11:38:46 +0100 Subject: [PATCH 015/165] Add dependabot config --- .github/dependabot.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..3f541100 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: +- package-ecosystem: pip + directory: "/" + schedule: + interval: daily +- package-ecosystem: npm + directory: "/" + schedule: + interval: daily +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily From 44b2273396130466151a4972bbdb8de473fb5e96 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 6 Mar 2021 12:08:00 +0100 Subject: [PATCH 016/165] Switch to latest chromedriver version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf69a668..6c2a9796 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: - name: Install Selenium run: | mkdir bin - curl -O https://chromedriver.storage.googleapis.com/77.0.3865.40/chromedriver_linux64.zip + curl -O https://chromedriver.storage.googleapis.com/`curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip unzip chromedriver_linux64.zip -d bin - uses: actions/checkout@v1 - name: Install dependencies From fcea539712fbfe16444b5238d0f61c272dd8064b Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 6 Mar 2021 12:08:24 +0100 Subject: [PATCH 017/165] Resolve pytest deprecation warning --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index e8d3455c..b5e37416 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,7 +21,7 @@ def random_name(n): return "-".join([x.capitalize() for x in words]) -@pytest.yield_fixture(scope="session") +@pytest.fixture(scope="session") def driver(): chrome_options = webdriver.ChromeOptions() chrome_options.headless = True From c093aab18cde572272fa6217a482fc875099d17f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Mar 2021 11:10:40 +0000 Subject: [PATCH 018/165] Bump actions/setup-node from v1 to v2.1.5 Bumps [actions/setup-node](https://github.com/actions/setup-node) from v1 to v2.1.5. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v1...46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea) Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c2a9796..944f2100 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2.1.5 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 699b3186..c3fefcfa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2.1.5 - uses: actions/setup-python@v1 - uses: actions/checkout@v2 - run: python set_version.py From 05556e19527ddbb029f7307da469cadbf0c22c7a Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 6 Mar 2021 12:00:52 +0100 Subject: [PATCH 019/165] Resolve #39 -- Make default search more like Django admin Different to before we now match search terms only if all bits match or the entire statement. The last part differs from the behavior in Django admin, which does not inlcude exact machtes of the entire search term inlcude spaces. Partially revert 07054b2d8ff15144c6b1b00577f3c898d47712bc --- django_select2/forms.py | 29 +++++++++++++++++------------ tests/test_forms.py | 2 +- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index 76fc525a..2aac9e6a 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -46,12 +46,14 @@ :parts: 1 """ -import re +import operator import uuid +from functools import reduce from itertools import chain from pickle import PicklingError # nosec from django import forms +from django.contrib.admin.utils import lookup_needs_distinct from django.contrib.admin.widgets import SELECT2_TRANSLATIONS from django.core import signing from django.db.models import Q @@ -315,8 +317,6 @@ class HeavySelect2TagWidget(HeavySelect2Mixin, Select2TagWidget): class ModelSelect2Mixin: """Widget mixin that provides attributes and methods for :class:`.AutoResponseView`.""" - _word_split_pattern = re.compile(r"\t|\n| ") - model = None queryset = None search_fields = [] @@ -400,19 +400,24 @@ def filter_queryset(self, request, term, queryset=None, **dependent_fields): search_fields = self.get_search_fields() select = Q() - if term != "": - for field in search_fields: - field_select = Q(**{field: term}) - if "contains" in field: - for word in filter(None, self._word_split_pattern.split(term)): - field_select |= Q(**{field: word}) - - select |= field_select + use_distinct = False + if search_fields and term: + for bit in term.split(): + or_queries = [Q(**{orm_lookup: bit}) for orm_lookup in search_fields] + select &= reduce(operator.or_, or_queries) + or_queries = [Q(**{orm_lookup: term}) for orm_lookup in search_fields] + select |= reduce(operator.or_, or_queries) + use_distinct |= any( + lookup_needs_distinct(queryset.model._meta, search_spec) + for search_spec in search_fields + ) if dependent_fields: select &= Q(**dependent_fields) - return queryset.filter(select).distinct() + if use_distinct: + queryset.filter(select).distinct() + return queryset.filter(select) def get_queryset(self): """ diff --git a/tests/test_forms.py b/tests/test_forms.py index 85b9265a..96fe3e6a 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -482,7 +482,7 @@ def test_filter_queryset__contains(self, genres): assert qs.exists() qs = widget.filter_queryset(None, "NOT Gen") - assert qs.exists(), "contains works even if only one part matches" + assert not qs.exists(), "contains works even if all bits match" def test_filter_queryset__multiple_fields(self, genres): genre = Genre.objects.create(title="Space Genre") From dc91f0305ef979957983fe2a6c09a38af640addf Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Mon, 29 Mar 2021 17:35:56 +0200 Subject: [PATCH 020/165] Add support for dependent m2m fields --- django_select2/views.py | 15 ++++++++++++--- tests/test_forms.py | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/django_select2/views.py b/django_select2/views.py index ec541d11..6295c519 100644 --- a/django_select2/views.py +++ b/django_select2/views.py @@ -51,11 +51,20 @@ def get_queryset(self): kwargs = { model_field_name: self.request.GET.get(form_field_name) for form_field_name, model_field_name in self.widget.dependent_fields.items() - if form_field_name in self.request.GET - and self.request.GET.get(form_field_name, "") != "" } + kwargs.update( + { + f"{model_field_name}__in": filter( + None, self.request.GET.get(f"{form_field_name}[]", "").split(",") + ) + for form_field_name, model_field_name in self.widget.dependent_fields.items() + } + ) return self.widget.filter_queryset( - self.request, self.term, self.queryset, **kwargs + self.request, + self.term, + self.queryset, + **{k: v for k, v in kwargs.items() if v}, ) def get_paginate_by(self, queryset): diff --git a/tests/test_forms.py b/tests/test_forms.py index 96fe3e6a..9487e428 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -200,7 +200,7 @@ def test_empty_css_setting(self, settings): settings.SELECT2_CSS = "" sut = Select2Widget() result = sut.media.render() - assert ".css" not in result + assert "/select2.css" not in result class TestHeavySelect2Mixin(TestSelect2Mixin): From b1b229f5464a746132f26ba44114c619e2ec9c47 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Mon, 29 Mar 2021 17:43:24 +0200 Subject: [PATCH 021/165] Add css support for Django admin --- MANIFEST.in | 1 + django_select2/forms.py | 2 +- django_select2/static/django_select2/django_select2.css | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 django_select2/static/django_select2/django_select2.css diff --git a/MANIFEST.in b/MANIFEST.in index 33ef41f2..d6400132 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ include django_select2/static/django_select2/django_select2.js +include django_select2/static/django_select2/django_select2.css prune tests prune .github exclude .fussyfox.yml diff --git a/django_select2/forms.py b/django_select2/forms.py index 2aac9e6a..0cccb132 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -121,7 +121,7 @@ def _get_media(self): return forms.Media( js=select2_js + i18n_file + ("django_select2/django_select2.js",), - css={"screen": select2_css}, + css={"screen": select2_css + ("django_select2/django_select2.css",)}, ) media = property(_get_media) diff --git a/django_select2/static/django_select2/django_select2.css b/django_select2/static/django_select2/django_select2.css new file mode 100644 index 00000000..09a93207 --- /dev/null +++ b/django_select2/static/django_select2/django_select2.css @@ -0,0 +1,3 @@ +.change-form select.django-select2 { + width: 20em; +} From 13d6a40796a5bf4d9006fbf1696c2ede0540e786 Mon Sep 17 00:00:00 2001 From: Cleiton Lima Date: Wed, 31 Mar 2021 19:06:05 -0300 Subject: [PATCH 022/165] Added *.egg-info in .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 875d21f9..d1ef58f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ *.pyc -Django_Select2.egg-info -Django_Select2_Py3.egg-info +*.egg-info dist build From 62d85d57dabe595199201104c57c14ea9be95d78 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 13 Apr 2021 17:26:38 +0200 Subject: [PATCH 023/165] Fix #52 -- Get all dependent field values --- django_select2/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/django_select2/views.py b/django_select2/views.py index 6295c519..c03f683e 100644 --- a/django_select2/views.py +++ b/django_select2/views.py @@ -54,8 +54,8 @@ def get_queryset(self): } kwargs.update( { - f"{model_field_name}__in": filter( - None, self.request.GET.get(f"{form_field_name}[]", "").split(",") + 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() } From 3448ce758b95ec4ce77187418a7e2a11f3fb214b Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 13 Apr 2021 17:27:17 +0200 Subject: [PATCH 024/165] Fix distinct results --- django_select2/forms.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index 0cccb132..2a88c215 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -415,8 +415,13 @@ def filter_queryset(self, request, term, queryset=None, **dependent_fields): if dependent_fields: select &= Q(**dependent_fields) + use_distinct |= any( + lookup_needs_distinct(queryset.model._meta, search_spec) + for search_spec in dependent_fields.keys() + ) + if use_distinct: - queryset.filter(select).distinct() + return queryset.filter(select).distinct() return queryset.filter(select) def get_queryset(self): From 038026c2f96d41810de567a7c159655c30bee46f Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Tue, 13 Apr 2021 17:51:17 +0200 Subject: [PATCH 025/165] Add Django 3.2 to CI suite --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 944f2100..3ac48048 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,7 @@ jobs: django-version: - "2.2" - "3.1" + - "3.2" runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} From fcd825dca416cea440d23e3dd68ec184447c50dd Mon Sep 17 00:00:00 2001 From: Arne Bertrand Date: Mon, 19 Apr 2021 17:48:35 +0200 Subject: [PATCH 026/165] Clarify that cache is not strictly necessary (#16) --- docs/index.rst | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 6f8b0d26..0ae73cbd 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,9 +21,21 @@ Add ``django_select`` to your URL root configuration: # … other patterns ] -Finally make sure you have a persistent cache backend setup (NOT -:class:`.DummyCache` or :class:`.LocMemCache`), we will use Redis in this -example. Make sure you have a Redis server up and running:: + +``django-select2`` requires a cache backend which is **persistent** +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 +you scale up into multiple servers. + +Below is an example setup using Redis, which is a solution that +works for multi-server setups: + +Make sure you have a Redis server up and running:: # Debian sudo apt-get install redis-server From c049b30b0858ebe819f88e3167be41a2edc4ccc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 May 2021 06:03:55 +0000 Subject: [PATCH 027/165] Bump actions/checkout from 2 to 2.3.4 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 2.3.4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v2.3.4) Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ac48048..5d8a0ff2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,14 +12,14 @@ jobs: steps: - uses: actions/setup-python@v2 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - run: python setup.py sdist bdist_wheel - run: python -m twine check dist/* standardjs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - uses: actions/setup-node@v2.1.5 with: node-version: '12.x' @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/setup-python@v2 - run: python -m pip install -U setuptools wheel - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - run: sudo apt-get install -y gettext graphviz - run: python setup.py develop - run: python setup.py build_sphinx -W -b doctest -b html @@ -62,7 +62,7 @@ jobs: mkdir bin curl -O https://chromedriver.storage.googleapis.com/`curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip unzip chromedriver_linux64.zip -d bin - - uses: actions/checkout@v1 + - uses: actions/checkout@v2.3.4 - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel codecov diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c3fefcfa..fe339400 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-python@v2 - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine - name: Build dist packages @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/setup-node@v2.1.5 - uses: actions/setup-python@v1 - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - run: python set_version.py - name: Upload packages run: npm publish From c1900dd737f29e853c561b64ac9edf45ada1e846 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 May 2021 07:42:28 +0000 Subject: [PATCH 028/165] Bump actions/setup-python from 2 to 2.2.2 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 2.2.2. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2...v2.2.2) Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/release.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d8a0ff2..28bcb854 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: dist: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v2.2.2 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - uses: actions/checkout@v2.3.4 - run: python setup.py sdist bdist_wheel @@ -29,7 +29,7 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v2.2.2 - run: python -m pip install -U setuptools wheel - uses: actions/checkout@v2.3.4 - run: sudo apt-get install -y gettext graphviz @@ -52,7 +52,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v2.2.2 with: python-version: ${{ matrix.python-version }} - name: Install Chrome diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe339400..ba9ca0f5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: PyPI: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v2.2.2 - uses: actions/checkout@v2.3.4 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v2.1.5 - - uses: actions/setup-python@v1 + - uses: actions/setup-python@v2.2.2 - uses: actions/checkout@v2.3.4 - run: python set_version.py - name: Upload packages From 4ff262f707e827d0ea2ce4431ec5f0f6eba0fee0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jul 2021 05:05:49 +0000 Subject: [PATCH 029/165] Bump actions/setup-node from 2.1.5 to 2.2.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.1.5 to 2.2.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.1.5...v2.2.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28bcb854..5998b271 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.3.4 - - uses: actions/setup-node@v2.1.5 + - uses: actions/setup-node@v2.2.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba9ca0f5..4e23f082 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.1.5 + - uses: actions/setup-node@v2.2.0 - uses: actions/setup-python@v2.2.2 - uses: actions/checkout@v2.3.4 - run: python set_version.py From 4d51978cb93e5d07cc3d686911e9b0c5b6618758 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Jul 2021 05:05:57 +0000 Subject: [PATCH 030/165] Bump actions/setup-node from 2.2.0 to 2.3.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.2.0 to 2.3.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.2.0...v2.3.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5998b271..f7aca8c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.3.4 - - uses: actions/setup-node@v2.2.0 + - uses: actions/setup-node@v2.3.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4e23f082..675a0160 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.2.0 + - uses: actions/setup-node@v2.3.0 - uses: actions/setup-python@v2.2.2 - uses: actions/checkout@v2.3.4 - run: python set_version.py From 09dbceb6ba1f92fcb6747afdb61ad500d4e56cde Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Aug 2021 05:06:29 +0000 Subject: [PATCH 031/165] Bump actions/setup-node from 2.3.0 to 2.3.1 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.3.0 to 2.3.1. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.3.0...v2.3.1) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7aca8c0..4e134a53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.3.4 - - uses: actions/setup-node@v2.3.0 + - uses: actions/setup-node@v2.3.1 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 675a0160..a6a467d9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.3.0 + - uses: actions/setup-node@v2.3.1 - uses: actions/setup-python@v2.2.2 - uses: actions/checkout@v2.3.4 - run: python set_version.py From d6e1ab3d61caac79a259732aedbd667cbf910915 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Aug 2021 05:06:58 +0000 Subject: [PATCH 032/165] Bump actions/setup-node from 2.3.1 to 2.3.2 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.3.1 to 2.3.2. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.3.1...v2.3.2) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e134a53..94df296b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.3.4 - - uses: actions/setup-node@v2.3.1 + - uses: actions/setup-node@v2.3.2 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a6a467d9..fb5901a9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.3.1 + - uses: actions/setup-node@v2.3.2 - uses: actions/setup-python@v2.2.2 - uses: actions/checkout@v2.3.4 - run: python set_version.py From bfc9313af4a738ca22580dc124916f9c4b0a4c5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Aug 2021 05:08:45 +0000 Subject: [PATCH 033/165] Bump actions/setup-node from 2.3.2 to 2.4.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.3.2 to 2.4.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.3.2...v2.4.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94df296b..b246a9d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.3.4 - - uses: actions/setup-node@v2.3.2 + - uses: actions/setup-node@v2.4.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fb5901a9..4e964edb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.3.2 + - uses: actions/setup-node@v2.4.0 - uses: actions/setup-python@v2.2.2 - uses: actions/checkout@v2.3.4 - run: python set_version.py From 1125ced364b2d716bd8e22389d6938ca4c330f11 Mon Sep 17 00:00:00 2001 From: Cleiton Lima Date: Tue, 21 Sep 2021 12:27:15 -0300 Subject: [PATCH 034/165] Added lang attribute to widgets --- django_select2/forms.py | 33 ++++++++++++++++----------------- tests/test_forms.py | 13 +++++++++++++ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index 2a88c215..98079386 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -76,9 +76,16 @@ class Select2Mixin: empty_label = "" + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.i18n_name = SELECT2_TRANSLATIONS.get(get_language()) + def build_attrs(self, base_attrs, extra_attrs=None): """Add select2 data attributes.""" - default_attrs = {"data-minimum-input-length": 0} + default_attrs = { + "lang": self.i18n_name, + "data-minimum-input-length": 0, + } if self.is_required: default_attrs["data-allow-clear"] = "false" else: @@ -100,32 +107,28 @@ def optgroups(self, name, value, attrs=None): self.choices = list(chain([("", "")], self.choices)) return super().optgroups(name, value, attrs=attrs) - def _get_media(self): + @property + def media(self): """ Construct Media as a dynamic property. .. Note:: For more information visit https://docs.djangoproject.com/en/stable/topics/forms/media/#media-as-a-dynamic-property """ - lang = get_language() select2_js = (settings.SELECT2_JS,) if settings.SELECT2_JS else () select2_css = (settings.SELECT2_CSS,) if settings.SELECT2_CSS else () - i18n_name = SELECT2_TRANSLATIONS.get(lang) - if i18n_name not in settings.SELECT2_I18N_AVAILABLE_LANGUAGES: - i18n_name = None - - i18n_file = ( - ("%s/%s.js" % (settings.SELECT2_I18N_PATH, i18n_name),) if i18n_name else () - ) + i18n_file = () + if self.i18n_name in settings.SELECT2_I18N_AVAILABLE_LANGUAGES: + i18n_file = ( + ("%s/%s.js" % (settings.SELECT2_I18N_PATH, self.i18n_name),) + ) return forms.Media( js=select2_js + i18n_file + ("django_select2/django_select2.js",), css={"screen": select2_css + ("django_select2/django_select2.css",)}, ) - media = property(_get_media) - class Select2TagMixin: """Mixin to add select2 tag functionality.""" @@ -212,11 +215,7 @@ def __init__(self, attrs=None, choices=(), **kwargs): Value is a name of a field in a model (used in `queryset`). """ - self.choices = choices - if attrs is not None: - self.attrs = attrs.copy() - else: - self.attrs = {} + super().__init__(attrs, choices) self.uuid = str(uuid.uuid4()) self.field_id = signing.dumps(self.uuid) diff --git a/tests/test_forms.py b/tests/test_forms.py index 9487e428..af988845 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -3,6 +3,7 @@ from collections.abc import Iterable import pytest +from django.contrib.admin.widgets import SELECT2_TRANSLATIONS from django.db.models import QuerySet from django.urls import reverse from django.utils import translation @@ -46,6 +47,12 @@ def test_initial_form_class(self): assert "my-class" in widget.render("name", None) assert "django-select2" in widget.render("name", None) + @pytest.mark.parametrize("code,name", SELECT2_TRANSLATIONS.items()) + def test_lang_attr(self, code, name): + translation.activate(code) + widget = self.widget_cls() + assert f'lang="{name}"' in widget.render("name", None) + def test_allow_clear(self, db): required_field = self.form.fields["artist"] assert required_field.required is True @@ -219,6 +226,12 @@ def test_initial_form_class(self): "name", None ) + @pytest.mark.parametrize("code,name", SELECT2_TRANSLATIONS.items()) + def test_lang_attr(self, code, name): + translation.activate(code) + widget = self.widget_cls(data_view="heavy_data_1") + assert f'lang="{name}"' in widget.render("name", None) + def test_selected_option(self, db): not_required_field = self.form.fields["primary_genre"] assert not_required_field.required is False From 820f2cb32c5ba67c15d03b5a59fb4956d5a11a0a Mon Sep 17 00:00:00 2001 From: Cleiton Lima Date: Tue, 21 Sep 2021 12:32:53 -0300 Subject: [PATCH 035/165] Added LANGUAGE_CODE for tests --- tests/testapp/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testapp/settings.py b/tests/testapp/settings.py index b5ded121..f46d128d 100644 --- a/tests/testapp/settings.py +++ b/tests/testapp/settings.py @@ -25,6 +25,7 @@ ("de", "German"), ("en", "English"), ] +LANGUAGE_CODE = "en" TEMPLATES = [ { From 742d92927405f6a33449c4b615863fa6dc2dc0b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Sep 2021 05:08:36 +0000 Subject: [PATCH 036/165] Bump actions/setup-node from 2.4.0 to 2.4.1 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.4.0 to 2.4.1. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.4.0...v2.4.1) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b246a9d8..ffd86bcc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.3.4 - - uses: actions/setup-node@v2.4.0 + - uses: actions/setup-node@v2.4.1 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4e964edb..e921a106 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.4.0 + - uses: actions/setup-node@v2.4.1 - uses: actions/setup-python@v2.2.2 - uses: actions/checkout@v2.3.4 - run: python set_version.py From f94e17678a16112ed64d536e4325e3c6f3870b43 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 2 Oct 2021 13:59:21 +0200 Subject: [PATCH 037/165] Resolve #92 -- Add tests to sdist package --- MANIFEST.in | 1 - 1 file changed, 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index d6400132..28040cc0 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,5 @@ include django_select2/static/django_select2/django_select2.js include django_select2/static/django_select2/django_select2.css -prune tests prune .github exclude .fussyfox.yml exclude .travis.yml From 581e2d15f516a6926a90915ff2861da19c184874 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 2 Oct 2021 14:10:31 +0200 Subject: [PATCH 038/165] Remove other unneeded files --- MANIFEST.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 28040cc0..45907113 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,5 @@ include django_select2/static/django_select2/django_select2.js include django_select2/static/django_select2/django_select2.css prune .github -exclude .fussyfox.yml -exclude .travis.yml -exclude .gitignore +exclude .* + From 36f9ac06947b7a271cdc2eec64169abb06755dc9 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 2 Oct 2021 14:50:57 +0200 Subject: [PATCH 039/165] Add Django 4.0 compatibility --- django_select2/forms.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index 98079386..86ca0390 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -52,8 +52,8 @@ from itertools import chain from pickle import PicklingError # nosec +import django from django import forms -from django.contrib.admin.utils import lookup_needs_distinct from django.contrib.admin.widgets import SELECT2_TRANSLATIONS from django.core import signing from django.db.models import Q @@ -64,6 +64,11 @@ from .cache import cache from .conf import settings +if django.VERSION < (4, 0): + from django.contrib.admin.utils import lookup_needs_distinct as lookup_spawns_duplicates +else: + from django.contrib.admin.utils import lookup_spawns_duplicates + class Select2Mixin: """ @@ -407,7 +412,7 @@ def filter_queryset(self, request, term, queryset=None, **dependent_fields): or_queries = [Q(**{orm_lookup: term}) for orm_lookup in search_fields] select |= reduce(operator.or_, or_queries) use_distinct |= any( - lookup_needs_distinct(queryset.model._meta, search_spec) + lookup_spawns_duplicates(queryset.model._meta, search_spec) for search_spec in search_fields ) @@ -415,7 +420,7 @@ def filter_queryset(self, request, term, queryset=None, **dependent_fields): select &= Q(**dependent_fields) use_distinct |= any( - lookup_needs_distinct(queryset.model._meta, search_spec) + lookup_spawns_duplicates(queryset.model._meta, search_spec) for search_spec in dependent_fields.keys() ) From e15ced997d376f986f4cb6c77eb70846733d7265 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 2 Oct 2021 14:53:18 +0200 Subject: [PATCH 040/165] Update version makers and Ci suite --- .github/workflows/ci.yml | 9 ++++++--- setup.cfg | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffd86bcc..aa472d42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,9 +46,12 @@ jobs: - "3.8" - "3.9" django-version: - - "2.2" - - "3.1" - - "3.2" + - "2.2.0" + - "3.2.0" + - "4.0a1" + exclude: + - python-version: "3.7" + django-version: "4.0a1" runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} diff --git a/setup.cfg b/setup.cfg index 98161532..317db187 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,9 +19,11 @@ classifier = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 Framework :: Django Framework :: Django :: 2.2 - Framework :: Django :: 3.0 + Framework :: Django :: 3.1 + Framework :: Django :: 4.0 [options] include_package_data = True From 1063fba8b34d858ddac2403ba22e8d36f24dc2be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Oct 2021 05:09:43 +0000 Subject: [PATCH 041/165] Bump actions/checkout from 2.3.4 to 2.3.5 Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.3.5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2.3.4...v2.3.5) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa472d42..1bd7e65a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,14 +12,14 @@ jobs: steps: - uses: actions/setup-python@v2.2.2 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v2.3.5 - run: python setup.py sdist bdist_wheel - run: python -m twine check dist/* standardjs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v2.3.5 - uses: actions/setup-node@v2.4.1 with: node-version: '12.x' @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/setup-python@v2.2.2 - run: python -m pip install -U setuptools wheel - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v2.3.5 - run: sudo apt-get install -y gettext graphviz - run: python setup.py develop - run: python setup.py build_sphinx -W -b doctest -b html @@ -65,7 +65,7 @@ jobs: mkdir bin curl -O https://chromedriver.storage.googleapis.com/`curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip unzip chromedriver_linux64.zip -d bin - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v2.3.5 - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel codecov diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e921a106..f014b665 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-python@v2.2.2 - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v2.3.5 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine - name: Build dist packages @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/setup-node@v2.4.1 - uses: actions/setup-python@v2.2.2 - - uses: actions/checkout@v2.3.4 + - uses: actions/checkout@v2.3.5 - run: python set_version.py - name: Upload packages run: npm publish From 5a835f37f4eb70ce8ef12b6682c252a61f3b9577 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Mon, 18 Oct 2021 15:45:21 +0200 Subject: [PATCH 042/165] Resolve #91 -- Add comment about cache expiration --- docs/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index 0ae73cbd..6ba1f8f3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -64,6 +64,12 @@ Next, add the cache configuration to your ``settings.py`` as follows: # Tell select2 which cache configuration to use: SELECT2_CACHE_BACKEND = "select2" +.. note:: + A custom timeout for your cache backend, will serve as an indirect session limit. + Auto select fields will stop working after, once the cache has expired. + It's recommended to use a dedicated cache database with an adequate + cache replacement policy such as LRU, FILO, etc. + External Dependencies --------------------- From 6bd7fb5f1edfbf5635fac0a0db1a7c6814bae137 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Nov 2021 05:06:19 +0000 Subject: [PATCH 043/165] Bump actions/checkout from 2.3.5 to 2.4.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.5 to 2.4.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2.3.5...v2.4.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1bd7e65a..ea6cb0e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,14 +12,14 @@ jobs: steps: - uses: actions/setup-python@v2.2.2 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - - uses: actions/checkout@v2.3.5 + - uses: actions/checkout@v2.4.0 - run: python setup.py sdist bdist_wheel - run: python -m twine check dist/* standardjs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.3.5 + - uses: actions/checkout@v2.4.0 - uses: actions/setup-node@v2.4.1 with: node-version: '12.x' @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/setup-python@v2.2.2 - run: python -m pip install -U setuptools wheel - - uses: actions/checkout@v2.3.5 + - uses: actions/checkout@v2.4.0 - run: sudo apt-get install -y gettext graphviz - run: python setup.py develop - run: python setup.py build_sphinx -W -b doctest -b html @@ -65,7 +65,7 @@ jobs: mkdir bin curl -O https://chromedriver.storage.googleapis.com/`curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip unzip chromedriver_linux64.zip -d bin - - uses: actions/checkout@v2.3.5 + - uses: actions/checkout@v2.4.0 - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel codecov diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f014b665..3deeaffc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-python@v2.2.2 - - uses: actions/checkout@v2.3.5 + - uses: actions/checkout@v2.4.0 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine - name: Build dist packages @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/setup-node@v2.4.1 - uses: actions/setup-python@v2.2.2 - - uses: actions/checkout@v2.3.5 + - uses: actions/checkout@v2.4.0 - run: python set_version.py - name: Upload packages run: npm publish From 5f0d76de317f17b883446ca008986ba6d2927a7a Mon Sep 17 00:00:00 2001 From: Greg Kaleka Date: Thu, 28 Oct 2021 16:54:41 -0700 Subject: [PATCH 044/165] Don't set default_app_config in Django 3.2 up As of Django 3.2, explicitly setting `default_app_config` [is deprecated](https://docs.djangoproject.com/en/3.2/releases/3.2/#features-deprecated-in-3-2). This check allows django-select2 to continue supporting earlier versions of Django while silencing this deprecation warning. --- django_select2/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/django_select2/__init__.py b/django_select2/__init__.py index 546ae234..d2d415b3 100644 --- a/django_select2/__init__.py +++ b/django_select2/__init__.py @@ -7,4 +7,7 @@ .. _Select2: https://select2.org/ """ -default_app_config = "django_select2.apps.Select2AppConfig" +from django import get_version + +if get_version() < '3.2': + default_app_config = "django_select2.apps.Select2AppConfig" From 3ef5fd164d93cc464cb564e0f9e5fe6d02951d5b Mon Sep 17 00:00:00 2001 From: Cleiton Lima Date: Tue, 2 Nov 2021 22:47:53 -0300 Subject: [PATCH 045/165] Added SELECT2_THEME settings --- django_select2/conf.py | 16 ++++++++++++++++ django_select2/forms.py | 18 ++++++++++-------- tests/test_forms.py | 17 +++++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/django_select2/conf.py b/django_select2/conf.py index 4d686005..8862932a 100644 --- a/django_select2/conf.py +++ b/django_select2/conf.py @@ -87,6 +87,14 @@ class Select2Conf(AppConf): SELECT2_CSS = 'assets/css/select2.css' + If you want to add more css (usually used in select2 themes), add a line + in settings.py like this:: + + SELECT2_CSS = [ + 'assets/css/select2.css', + 'assets/css/select2-theme.css', + ] + If you provide your own CSS and would not like Django-Select2 to load any, change this setting to a blank string like so:: @@ -96,6 +104,14 @@ class Select2Conf(AppConf): develop without an Internet connection. """ + THEME = "default" + """ + Select2 supports custom themes using the theme option so you can style Select2 + to match the rest of your application. + + .. tip:: When using other themes, you may need use select2 css and theme css. + """ + I18N_PATH = ( "https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bversion%7D/js/i18n".format( version=LIB_VERSION diff --git a/django_select2/forms.py b/django_select2/forms.py index 86ca0390..b40b6207 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -90,6 +90,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, } if self.is_required: default_attrs["data-allow-clear"] = "false" @@ -120,18 +121,19 @@ def media(self): .. Note:: For more information visit https://docs.djangoproject.com/en/stable/topics/forms/media/#media-as-a-dynamic-property """ - select2_js = (settings.SELECT2_JS,) if settings.SELECT2_JS else () - select2_css = (settings.SELECT2_CSS,) if settings.SELECT2_CSS else () + select2_js = [settings.SELECT2_JS] if settings.SELECT2_JS else [] + select2_css = settings.SELECT2_CSS if settings.SELECT2_CSS else [] - i18n_file = () + if isinstance(select2_css, str): + select2_css = [select2_css] + + i18n_file = [] if self.i18n_name in settings.SELECT2_I18N_AVAILABLE_LANGUAGES: - i18n_file = ( - ("%s/%s.js" % (settings.SELECT2_I18N_PATH, self.i18n_name),) - ) + i18n_file = [f"{settings.SELECT2_I18N_PATH}/{self.i18n_name}.js"] return forms.Media( - js=select2_js + i18n_file + ("django_select2/django_select2.js",), - css={"screen": select2_css + ("django_select2/django_select2.css",)}, + js=select2_js + i18n_file + ["django_select2/django_select2.js"], + css={"screen": select2_css + ["django_select2/django_select2.css"]}, ) diff --git a/tests/test_forms.py b/tests/test_forms.py index af988845..5a89dfd1 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -169,6 +169,11 @@ def test_i18n(self): "django_select2/django_select2.js", ) + def test_theme_setting(self, settings): + settings.SELECT2_THEME = "classic" + widget = self.widget_cls() + assert 'data-theme="classic"' in widget.render("name", None) + class TestSelect2MixinSettings: def test_default_media(self): @@ -209,6 +214,13 @@ def test_empty_css_setting(self, settings): result = sut.media.render() assert "/select2.css" not in result + def test_multiple_css_setting(self, settings): + settings.SELECT2_CSS = ["select2.css", "select2-theme.css"] + sut = Select2Widget() + result = sut.media.render() + assert "select2.css" in result + assert "select2-theme.css" in result + class TestHeavySelect2Mixin(TestSelect2Mixin): url = reverse("heavy_select2_widget") @@ -321,6 +333,11 @@ class NoPickle: with pytest.raises(NotImplementedError): widget.set_to_cache() + def test_theme_setting(self, settings): + settings.SELECT2_THEME = "classic" + widget = self.widget_cls(data_view="heavy_data_1") + assert 'data-theme="classic"' in widget.render("name", None) + class TestModelSelect2Mixin(TestHeavySelect2Mixin): form = forms.AlbumModelSelect2WidgetForm(initial={"primary_genre": 1}) From 8d74d47a9affe51639a8efb1cf5f786be8275720 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Nov 2021 05:05:44 +0000 Subject: [PATCH 046/165] Bump actions/setup-python from 2.2.2 to 2.3.0 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2.2.2 to 2.3.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2.2.2...v2.3.0) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/release.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea6cb0e2..ad19eb79 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: dist: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.2.2 + - uses: actions/setup-python@v2.3.0 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - uses: actions/checkout@v2.4.0 - run: python setup.py sdist bdist_wheel @@ -29,7 +29,7 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.2.2 + - uses: actions/setup-python@v2.3.0 - run: python -m pip install -U setuptools wheel - uses: actions/checkout@v2.4.0 - run: sudo apt-get install -y gettext graphviz @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v2.3.0 with: python-version: ${{ matrix.python-version }} - name: Install Chrome diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3deeaffc..1ce1e7ff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: PyPI: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.2.2 + - uses: actions/setup-python@v2.3.0 - uses: actions/checkout@v2.4.0 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v2.4.1 - - uses: actions/setup-python@v2.2.2 + - uses: actions/setup-python@v2.3.0 - uses: actions/checkout@v2.4.0 - run: python set_version.py - name: Upload packages From e88bfc266a7f5a997f0a9921aaeec86930fde03c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Nov 2021 05:08:21 +0000 Subject: [PATCH 047/165] Bump actions/setup-node from 2.4.1 to 2.5.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.4.1 to 2.5.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.4.1...v2.5.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad19eb79..74964894 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.4.0 - - uses: actions/setup-node@v2.4.1 + - uses: actions/setup-node@v2.5.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1ce1e7ff..f2f381b8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.4.1 + - uses: actions/setup-node@v2.5.0 - uses: actions/setup-python@v2.3.0 - uses: actions/checkout@v2.4.0 - run: python set_version.py From 153dda64ee9a8946ac32999a148877a5ac481407 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Nov 2021 08:47:12 +0000 Subject: [PATCH 048/165] Bump actions/setup-python from 2.3.0 to 2.3.1 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2.3.0 to 2.3.1. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2.3.0...v2.3.1) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/release.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74964894..7e30a0c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: dist: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.0 + - uses: actions/setup-python@v2.3.1 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - uses: actions/checkout@v2.4.0 - run: python setup.py sdist bdist_wheel @@ -29,7 +29,7 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.0 + - uses: actions/setup-python@v2.3.1 - run: python -m pip install -U setuptools wheel - uses: actions/checkout@v2.4.0 - run: sudo apt-get install -y gettext graphviz @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2.3.0 + uses: actions/setup-python@v2.3.1 with: python-version: ${{ matrix.python-version }} - name: Install Chrome diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f2f381b8..9d06a17e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: PyPI: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.0 + - uses: actions/setup-python@v2.3.1 - uses: actions/checkout@v2.4.0 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v2.5.0 - - uses: actions/setup-python@v2.3.0 + - uses: actions/setup-python@v2.3.1 - uses: actions/checkout@v2.4.0 - run: python set_version.py - name: Upload packages From b85895363f4f82d5f8774fdeb4eb6a1f59f26364 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Dec 2021 05:07:52 +0000 Subject: [PATCH 049/165] Bump actions/setup-node from 2.5.0 to 2.5.1 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.5.0 to 2.5.1. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.5.0...v2.5.1) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e30a0c1..2feb4772 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.4.0 - - uses: actions/setup-node@v2.5.0 + - uses: actions/setup-node@v2.5.1 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9d06a17e..047b387c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.5.0 + - uses: actions/setup-node@v2.5.1 - uses: actions/setup-python@v2.3.1 - uses: actions/checkout@v2.4.0 - run: python set_version.py From 6e7e45816a12f5a36feb71e23845141d68e35e34 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Thu, 3 Feb 2022 20:09:04 +0100 Subject: [PATCH 050/165] Add Select2 mixin that uses Django's own select template --- django_select2/__init__.py | 2 +- django_select2/forms.py | 29 ++++++++++++++++++++++++----- tests/test_forms.py | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/django_select2/__init__.py b/django_select2/__init__.py index d2d415b3..575a0213 100644 --- a/django_select2/__init__.py +++ b/django_select2/__init__.py @@ -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" diff --git a/django_select2/forms.py b/django_select2/forms.py index b40b6207..df3982fe 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -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 @@ -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 @@ -79,6 +81,9 @@ class Select2Mixin: form media. """ + css_class_name = "django-select2" + theme = None + empty_label = "" def __init__(self, *args, **kwargs): @@ -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" @@ -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): @@ -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.""" diff --git a/tests/test_forms.py b/tests/test_forms.py index 5a89dfd1..dc991ed2 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -21,6 +21,7 @@ ModelSelect2TagWidget, ModelSelect2Widget, Select2Widget, + Select2AdminMixin, ) from tests.testapp import forms from tests.testapp.forms import ( @@ -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/%7Bsettings.SELECT2_LIB_VERSION%7D/js/select2.min.js", + f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/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() From b62ed592135961f91e45d81fb07379dc48ad9d43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Feb 2022 05:09:06 +0000 Subject: [PATCH 051/165] Bump actions/setup-python from 2.3.1 to 2.3.2 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2.3.1 to 2.3.2. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2.3.1...v2.3.2) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/release.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2feb4772..2785d478 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: dist: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.1 + - uses: actions/setup-python@v2.3.2 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - uses: actions/checkout@v2.4.0 - run: python setup.py sdist bdist_wheel @@ -29,7 +29,7 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.1 + - uses: actions/setup-python@v2.3.2 - run: python -m pip install -U setuptools wheel - uses: actions/checkout@v2.4.0 - run: sudo apt-get install -y gettext graphviz @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2.3.1 + uses: actions/setup-python@v2.3.2 with: python-version: ${{ matrix.python-version }} - name: Install Chrome diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 047b387c..c176c751 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: PyPI: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.1 + - uses: actions/setup-python@v2.3.2 - uses: actions/checkout@v2.4.0 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v2.5.1 - - uses: actions/setup-python@v2.3.1 + - uses: actions/setup-python@v2.3.2 - uses: actions/checkout@v2.4.0 - run: python set_version.py - name: Upload packages From 22dafdad0aa3e2b833eb40500ffe5765e3389bc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Feb 2022 05:07:12 +0000 Subject: [PATCH 052/165] Bump actions/setup-node from 2.5.1 to 3.0.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2.5.1 to 3.0.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v2.5.1...v3.0.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2785d478..e558719e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2.4.0 - - uses: actions/setup-node@v2.5.1 + - uses: actions/setup-node@v3.0.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c176c751..15e67e23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v2.5.1 + - uses: actions/setup-node@v3.0.0 - uses: actions/setup-python@v2.3.2 - uses: actions/checkout@v2.4.0 - run: python set_version.py From b5ee6bcd90177f46cfeea08ed0a5e27d149fbe47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Mar 2022 05:06:15 +0000 Subject: [PATCH 053/165] Bump actions/setup-python from 2.3.2 to 3 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2.3.2 to 3. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2.3.2...v3) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/release.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e558719e..b7cfe489 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: dist: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.2 + - uses: actions/setup-python@v3 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - uses: actions/checkout@v2.4.0 - run: python setup.py sdist bdist_wheel @@ -29,7 +29,7 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.2 + - uses: actions/setup-python@v3 - run: python -m pip install -U setuptools wheel - uses: actions/checkout@v2.4.0 - run: sudo apt-get install -y gettext graphviz @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2.3.2 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} - name: Install Chrome diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 15e67e23..612a15cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: PyPI: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2.3.2 + - uses: actions/setup-python@v3 - uses: actions/checkout@v2.4.0 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v3.0.0 - - uses: actions/setup-python@v2.3.2 + - uses: actions/setup-python@v3 - uses: actions/checkout@v2.4.0 - run: python set_version.py - name: Upload packages From f099b26afd84dbb43127f34336a8a58a487b13ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Mar 2022 05:10:00 +0000 Subject: [PATCH 054/165] Bump actions/checkout from 2.4.0 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2.4.0 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2.4.0...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7cfe489..0e0980b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,14 +12,14 @@ jobs: steps: - uses: actions/setup-python@v3 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - run: python setup.py sdist bdist_wheel - run: python -m twine check dist/* standardjs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - uses: actions/setup-node@v3.0.0 with: node-version: '12.x' @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/setup-python@v3 - run: python -m pip install -U setuptools wheel - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - run: sudo apt-get install -y gettext graphviz - run: python setup.py develop - run: python setup.py build_sphinx -W -b doctest -b html @@ -65,7 +65,7 @@ jobs: mkdir bin curl -O https://chromedriver.storage.googleapis.com/`curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip unzip chromedriver_linux64.zip -d bin - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel codecov diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 612a15cf..38b1f3cd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-python@v3 - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine - name: Build dist packages @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/setup-node@v3.0.0 - uses: actions/setup-python@v3 - - uses: actions/checkout@v2.4.0 + - uses: actions/checkout@v3 - run: python set_version.py - name: Upload packages run: npm publish From e67069d99c866755f33a4a0973cfcd255a4e7f4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Apr 2022 05:10:36 +0000 Subject: [PATCH 055/165] Bump actions/setup-node from 3.0.0 to 3.1.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.0.0...v3.1.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e0980b2..48b51ba9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3.0.0 + - uses: actions/setup-node@v3.1.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 38b1f3cd..9320eb8e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v3.0.0 + - uses: actions/setup-node@v3.1.0 - uses: actions/setup-python@v3 - uses: actions/checkout@v3 - run: python set_version.py From b292322a499e53d36196366f799fd39b49e8eb82 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Fri, 8 Apr 2022 14:39:15 +0200 Subject: [PATCH 056/165] Fix #133 -- Remove double dependency entry --- setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 317db187..e61d80d4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -54,7 +54,6 @@ universal = 1 [bdist_rpm] requires = python-django-appconf >= 2.0 - python-django-appconf >= 0.6 [aliases] test = pytest From e6be444999c25374a263c70356293d9fee30e293 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Apr 2022 09:47:47 +0000 Subject: [PATCH 057/165] Bump actions/setup-node from 3.1.0 to 3.1.1 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.1.0...v3.1.1) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48b51ba9..a5e8aa04 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3.1.0 + - uses: actions/setup-node@v3.1.1 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9320eb8e..78352ac3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v3.1.0 + - uses: actions/setup-node@v3.1.1 - uses: actions/setup-python@v3 - uses: actions/checkout@v3 - run: python set_version.py From 0449db9468f41ed5da7683986657cfd3a3e9cea6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 May 2022 05:10:42 +0000 Subject: [PATCH 058/165] Bump actions/setup-node from 3.1.1 to 3.2.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.1.1 to 3.2.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.1.1...v3.2.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5e8aa04..7b85e5ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3.1.1 + - uses: actions/setup-node@v3.2.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 78352ac3..64cca2ac 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v3.1.1 + - uses: actions/setup-node@v3.2.0 - uses: actions/setup-python@v3 - uses: actions/checkout@v3 - run: python set_version.py From d7b079ecbaa137f80dc7f1778788e6e6a72c85e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jun 2022 05:07:52 +0000 Subject: [PATCH 059/165] Bump actions/setup-node from 3.2.0 to 3.3.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.2.0...v3.3.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b85e5ce..12d2ee08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3.2.0 + - uses: actions/setup-node@v3.3.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 64cca2ac..e8e524dc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v3.2.0 + - uses: actions/setup-node@v3.3.0 - uses: actions/setup-python@v3 - uses: actions/checkout@v3 - run: python set_version.py From 01550b901e5fba4e13467df37383cab667a5902c Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Wed, 8 Jun 2022 10:20:01 +0200 Subject: [PATCH 060/165] Fix #141 -- Create .readthedocs.yaml --- .readthedocs.yaml | 21 +++++++++++++++++++++ setup.cfg | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..4fa27769 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,21 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-20.04 + tools: + python: "3.10" + +sphinx: + configuration: docs/conf.py + + +python: + install: + - method: pip + path: . + extra_requirements: + - docs diff --git a/setup.cfg b/setup.cfg index e61d80d4..638154f0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,6 +47,8 @@ test = pytest-cov pytest-django selenium +docs = + sphinx [bdist_wheel] universal = 1 From ba0de98a50a5fab2204f94bf10d6eb97f34d674a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Jul 2022 05:07:51 +0000 Subject: [PATCH 061/165] Bump actions/setup-node from 3.3.0 to 3.4.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.3.0...v3.4.0) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12d2ee08..76237e7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3.3.0 + - uses: actions/setup-node@v3.4.0 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e8e524dc..016c32ed 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v3.3.0 + - uses: actions/setup-node@v3.4.0 - uses: actions/setup-python@v3 - uses: actions/checkout@v3 - run: python set_version.py From be3520912bcd5b9879ce4db749272cc685f26284 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Jul 2022 05:08:16 +0000 Subject: [PATCH 062/165] Bump actions/setup-node from 3.4.0 to 3.4.1 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3.4.0...v3.4.1) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76237e7e..c4f1264d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3.4.0 + - uses: actions/setup-node@v3.4.1 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 016c32ed..04235ad7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: npm: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v3.4.0 + - uses: actions/setup-node@v3.4.1 - uses: actions/setup-python@v3 - uses: actions/checkout@v3 - run: python set_version.py From 731e176126595230377130ddd47b0a3b5c727e53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Jul 2022 09:19:49 +0000 Subject: [PATCH 063/165] Bump actions/setup-python from 3 to 4.1.0 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 3 to 4.1.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v3...v4.1.0) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/release.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4f1264d..f0ccd223 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: dist: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - uses: actions/checkout@v3 - run: python setup.py sdist bdist_wheel @@ -29,7 +29,7 @@ jobs: docs: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 - run: python -m pip install -U setuptools wheel - uses: actions/checkout@v3 - run: sudo apt-get install -y gettext graphviz @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install Chrome diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 04235ad7..19101a23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: PyPI: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 - uses: actions/checkout@v3 - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v3.4.1 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 - uses: actions/checkout@v3 - run: python set_version.py - name: Upload packages From ab11ceac9a2ea13fee9eb896dbeaa651dfcf7421 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Mon, 1 Aug 2022 18:17:57 +0200 Subject: [PATCH 064/165] Set explicit python version --- .github/workflows/ci.yml | 8 ++++++-- .github/workflows/release.yml | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0ccd223..4e08a8cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,9 +10,11 @@ jobs: dist: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v3 - uses: actions/setup-python@v4 + with: + python-version: "3.10" - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - - uses: actions/checkout@v3 - run: python setup.py sdist bdist_wheel - run: python -m twine check dist/* @@ -29,9 +31,11 @@ jobs: docs: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v3 - uses: actions/setup-python@v4 + with: + python-version: "3.10" - run: python -m pip install -U setuptools wheel - - uses: actions/checkout@v3 - run: sudo apt-get install -y gettext graphviz - run: python setup.py develop - run: python setup.py build_sphinx -W -b doctest -b html diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 19101a23..de592fa6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,8 +8,10 @@ jobs: PyPI: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v4 - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.10" - name: Install Python dependencies run: python -m pip install --upgrade pip setuptools wheel twine - name: Build dist packages @@ -23,9 +25,11 @@ jobs: npm: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v3 - uses: actions/setup-node@v3.4.1 - uses: actions/setup-python@v4 - - uses: actions/checkout@v3 + with: + python-version: "3.10" - run: python set_version.py - name: Upload packages run: npm publish From 08822ca3710ee37a050616467614af938a5d23d0 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 9 Sep 2022 11:57:34 +0100 Subject: [PATCH 065/165] Support Django 4.1 --- .github/workflows/ci.yml | 13 ++++++++----- setup.cfg | 1 + tests/testapp/settings.py | 6 +++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e08a8cf..abde664c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,12 +50,15 @@ jobs: - "3.8" - "3.9" django-version: - - "2.2.0" - - "3.2.0" - - "4.0a1" + - "2.2" + - "3.2" + - "4.0" + - "4.1" exclude: - python-version: "3.7" - django-version: "4.0a1" + django-version: "4.0" + - python-version: "3.7" + django-version: "4.1" runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} @@ -76,7 +79,7 @@ jobs: pip install -e .[test] pip install django~=${{ matrix.django-version }} - name: Run tests - run: PATH=$PATH:$(pwd)/bin py.test + run: PATH=$PATH:$(pwd)/bin pytest - run: codecov env: CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} diff --git a/setup.cfg b/setup.cfg index 638154f0..ec11807a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,6 +24,7 @@ classifier = Framework :: Django :: 2.2 Framework :: Django :: 3.1 Framework :: Django :: 4.0 + Framework :: Django :: 4.1 [options] include_package_data = True diff --git a/tests/testapp/settings.py b/tests/testapp/settings.py index f46d128d..15b29b59 100644 --- a/tests/testapp/settings.py +++ b/tests/testapp/settings.py @@ -1,5 +1,7 @@ import os.path +import django + BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DEBUG = True @@ -37,5 +39,7 @@ SECRET_KEY = "123456" -USE_L10N = True +if django.VERSION < (4, 0): + USE_L10N = True USE_I18N = True +USE_TZ = True From a5aafd7cec43390c69ca3f5c7bd0f0824e214823 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 9 Sep 2022 12:10:40 +0100 Subject: [PATCH 066/165] Python 3.10, fix for removals in selenium --- .github/workflows/ci.yml | 1 + setup.cfg | 1 + tests/test_forms.py | 64 ++++++++++++++++++++-------------------- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abde664c..8e9a0ccf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,7 @@ jobs: - "3.7" - "3.8" - "3.9" + - "3.10" django-version: - "2.2" - "3.2" diff --git a/setup.cfg b/setup.cfg index ec11807a..e75f3704 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,6 +20,7 @@ classifier = Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Framework :: Django Framework :: Django :: 2.2 Framework :: Django :: 3.1 diff --git a/tests/test_forms.py b/tests/test_forms.py index dc991ed2..70a89d55 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -85,22 +85,22 @@ def test_allow_clear(self, db): def test_no_js_error(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): - error = driver.find_element_by_xpath("//body[@JSError]") + error = driver.find_element(By.XPATH, "//body[@JSError]") pytest.fail(error.get_attribute("JSError")) def test_selecting(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): - driver.find_element_by_css_selector(".select2-results") - elem = driver.find_element_by_css_selector(".select2-selection") + driver.find_element(By.CSS_SELECTOR, ".select2-results") + elem = driver.find_element(By.CSS_SELECTOR, ".select2-selection") elem.click() - results = driver.find_element_by_css_selector(".select2-results") + results = driver.find_element(By.CSS_SELECTOR, ".select2-results") assert results.is_displayed() is True - elem = results.find_element_by_css_selector(".select2-results__option") + elem = results.find_element(By.CSS_SELECTOR, ".select2-results__option") elem.click() with pytest.raises(NoSuchElementException): - error = driver.find_element_by_xpath("//body[@JSError]") + error = driver.find_element(By.XPATH, "//body[@JSError]") pytest.fail(error.get_attribute("JSError")) def test_data_url(http://github.com/self): @@ -301,12 +301,12 @@ def test_many_selected_option(self, db, genres): def test_multiple_widgets(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): - driver.find_element_by_css_selector(".select2-results") + driver.find_element(By.CSS_SELECTOR, ".select2-results") - elem1, elem2 = driver.find_elements_by_css_selector(".select2-selection") + elem1, elem2 = driver.find_elements(By.CSS_SELECTOR, ".select2-selection") elem1.click() - search1 = driver.find_element_by_css_selector(".select2-search__field") + search1 = driver.find_element(By.CSS_SELECTOR, ".select2-search__field") search1.send_keys("fo") result1 = ( WebDriverWait(driver, 60) @@ -319,7 +319,7 @@ def test_multiple_widgets(self, db, live_server, driver): ) elem2.click() - search2 = driver.find_element_by_css_selector(".select2-search__field") + search2 = driver.find_element(By.CSS_SELECTOR, ".select2-search__field") search2.send_keys("fo") result2 = ( WebDriverWait(driver, 60) @@ -334,7 +334,7 @@ def test_multiple_widgets(self, db, live_server, driver): assert result1 != result2 with pytest.raises(NoSuchElementException): - error = driver.find_element_by_xpath("//body[@JSError]") + error = driver.find_element(By.XPATH, "//body[@JSError]") pytest.fail(error.get_attribute("JSError")) def test_get_url(http://github.com/self): @@ -646,15 +646,15 @@ def test_widgets_selected_after_validation_error(self, db, live_server, driver): WebDriverWait(driver, 3).until( expected_conditions.presence_of_element_located((By.ID, "id_title")) ) - title = driver.find_element_by_id("id_title") + title = driver.find_element(By.ID, "id_title") title.send_keys("fo") - genres, fartists = driver.find_elements_by_css_selector( - ".select2-selection--multiple" + genres, fartists = driver.find_elements( + By.CSS_SELECTOR, ".select2-selection--multiple" ) genres.click() genres.send_keys("o") # results are Zero One Two Four # select second element - One - driver.find_element_by_css_selector(".select2-results li:nth-child(2)").click() + driver.find_element(By.CSS_SELECTOR, ".select2-results li:nth-child(2)").click() genres.submit() # there is a ValidationError raised, check for it errstring = ( @@ -668,8 +668,8 @@ def test_widgets_selected_after_validation_error(self, db, live_server, driver): ) assert errstring == "Title must have more than 3 characters." # genres should still have One as selected option - result_title = driver.find_element_by_css_selector( - ".select2-selection--multiple li" + result_title = driver.find_element( + By.CSS_SELECTOR, ".select2-selection--multiple li" ).get_attribute("title") assert result_title == "One" @@ -692,7 +692,7 @@ def test_widgets_selected_after_validation_error( country_container, city_container, city2_container, - ) = driver.find_elements_by_css_selector(".select2-selection--single") + ) = driver.find_elements(By.CSS_SELECTOR, ".select2-selection--single") # clicking city select2 lists all available cities city_container.click() @@ -701,7 +701,7 @@ def test_widgets_selected_after_validation_error( (By.CSS_SELECTOR, ".select2-results li") ) ) - city_options = driver.find_elements_by_css_selector(".select2-results li") + city_options = driver.find_elements(By.CSS_SELECTOR, ".select2-results li") city_names_from_browser = {option.text for option in city_options} city_names_from_db = set(City.objects.values_list("name", flat=True)) assert len(city_names_from_browser) == City.objects.count() @@ -714,8 +714,8 @@ def test_widgets_selected_after_validation_error( (By.CSS_SELECTOR, ".select2-results li:nth-child(2)") ) ) - country_option = driver.find_element_by_css_selector( - ".select2-results li:nth-child(2)" + country_option = driver.find_element( + By.CSS_SELECTOR, ".select2-results li:nth-child(2)" ) country_name = country_option.text country_option.click() @@ -728,7 +728,7 @@ def test_widgets_selected_after_validation_error( (By.CSS_SELECTOR, ".select2-results li") ) ) - city_options = driver.find_elements_by_css_selector(".select2-results li") + city_options = driver.find_elements(By.CSS_SELECTOR, ".select2-results li") city_names_from_browser = {option.text for option in city_options} city_names_from_db = set( Country.objects.get(name=country_name).cities.values_list("name", flat=True) @@ -737,8 +737,8 @@ def test_widgets_selected_after_validation_error( assert city_names_from_browser == city_names_from_db # selecting a city reaaly does it - city_option = driver.find_element_by_css_selector( - ".select2-results li:nth-child(2)" + city_option = driver.find_element( + By.CSS_SELECTOR, ".select2-results li:nth-child(2)" ) city_name = city_option.text city_option.click() @@ -751,7 +751,7 @@ def test_widgets_selected_after_validation_error( (By.CSS_SELECTOR, ".select2-results li") ) ) - country_options = driver.find_elements_by_css_selector(".select2-results li") + country_options = driver.find_elements(By.CSS_SELECTOR, ".select2-results li") country_names_from_browser = {option.text for option in country_options} country_names_from_db = {City.objects.get(name=city_name).country.name} assert len(country_names_from_browser) != Country.objects.count() @@ -765,7 +765,7 @@ def test_dependent_fields_clear_after_change_parent( country_container, city_container, city2_container, - ) = driver.find_elements_by_css_selector(".select2-selection--single") + ) = driver.find_elements(By.CSS_SELECTOR, ".select2-selection--single") # selecting a country really does it country_container.click() @@ -774,8 +774,8 @@ def test_dependent_fields_clear_after_change_parent( (By.CSS_SELECTOR, ".select2-results li:nth-child(2)") ) ) - country_option = driver.find_element_by_css_selector( - ".select2-results li:nth-child(2)" + country_option = driver.find_element( + By.CSS_SELECTOR, ".select2-results li:nth-child(2)" ) country_name = country_option.text country_option.click() @@ -788,8 +788,8 @@ def test_dependent_fields_clear_after_change_parent( (By.CSS_SELECTOR, ".select2-results li") ) ) - city2_option = driver.find_element_by_css_selector( - ".select2-results li:nth-child(2)" + city2_option = driver.find_element( + By.CSS_SELECTOR, ".select2-results li:nth-child(2)" ) city2_name = city2_option.text city2_option.click() @@ -802,8 +802,8 @@ def test_dependent_fields_clear_after_change_parent( (By.CSS_SELECTOR, ".select2-results li:nth-child(3)") ) ) - country_option = driver.find_element_by_css_selector( - ".select2-results li:nth-child(3)" + country_option = driver.find_element( + By.CSS_SELECTOR, ".select2-results li:nth-child(3)" ) country_name = country_option.text country_option.click() From 4a6122dae5aede2d957658afc796dcef85358bd7 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Fri, 9 Sep 2022 15:01:55 +0200 Subject: [PATCH 067/165] Remove Python 3.7 support --- .github/workflows/ci.yml | 6 ------ setup.cfg | 2 -- 2 files changed, 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e9a0ccf..06d750d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,6 @@ jobs: strategy: matrix: python-version: - - "3.7" - "3.8" - "3.9" - "3.10" @@ -55,11 +54,6 @@ jobs: - "3.2" - "4.0" - "4.1" - exclude: - - python-version: "3.7" - django-version: "4.0" - - python-version: "3.7" - django-version: "4.1" runs-on: ubuntu-latest steps: - name: Set up Python ${{ matrix.python-version }} diff --git a/setup.cfg b/setup.cfg index e75f3704..d386afe4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,8 +16,6 @@ classifier = Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 From bd9d1a5d8fc0c490c8fcbf3bf0b30a397bcdc175 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Fri, 9 Sep 2022 15:02:22 +0200 Subject: [PATCH 068/165] Remove Django 2.2 support --- .github/workflows/ci.yml | 1 - setup.cfg | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06d750d1..f49ecb46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,6 @@ jobs: - "3.9" - "3.10" django-version: - - "2.2" - "3.2" - "4.0" - "4.1" diff --git a/setup.cfg b/setup.cfg index d386afe4..c23691a0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,8 +20,7 @@ classifier = Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Framework :: Django - Framework :: Django :: 2.2 - Framework :: Django :: 3.1 + Framework :: Django :: 3.2 Framework :: Django :: 4.0 Framework :: Django :: 4.1 @@ -29,7 +28,7 @@ classifier = include_package_data = True packages = django_select2 install_requires = - django>=2.2 + django>=3.2 django-appconf>=0.6.0 setup_requires = setuptools_scm From 245450dc821f7710f3e030110b3bb5da4d5acc96 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Fri, 9 Sep 2022 15:02:43 +0200 Subject: [PATCH 069/165] Fix Django version install in CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f49ecb46..e0e31986 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,7 +71,7 @@ jobs: run: | python -m pip install --upgrade pip setuptools wheel codecov pip install -e .[test] - pip install django~=${{ matrix.django-version }} + pip install django~="${{ matrix.django-version }}.0" - name: Run tests run: PATH=$PATH:$(pwd)/bin pytest - run: codecov From 371c2235000d59f5355569b81b59d0eeb8223a45 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Fri, 9 Sep 2022 15:16:05 +0200 Subject: [PATCH 070/165] Update CI suite --- .github/workflows/ci.yml | 48 +++++++++++++++++++++-------------- .github/workflows/release.yml | 12 ++++----- setup.cfg | 9 ++----- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0e31986..f2b2b8f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: branches: - - master + - main pull_request: jobs: @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.x" - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - run: python setup.py sdist bdist_wheel - run: python -m twine check dist/* @@ -35,12 +35,11 @@ jobs: - uses: actions/setup-python@v4 with: python-version: "3.10" - - run: python -m pip install -U setuptools wheel - run: sudo apt-get install -y gettext graphviz - - run: python setup.py develop - - run: python setup.py build_sphinx -W -b doctest -b html + - run: python -m pip install -e .[docs] + - run: python -m sphinx -W -b doctest -b html docs docs/_build - pytest: + PyTest: needs: - standardjs strategy: @@ -55,10 +54,25 @@ jobs: - "4.1" runs-on: ubuntu-latest steps: - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + - run: python -m pip install Django~="${{ matrix.django-version }}.0" + - run: python -m pip install -e .[test] + - run: python -m pytest + - uses: codecov/codecov-action@v2 + + Selenium: + needs: + - standardjs + strategy: + matrix: + python-version: + - "3.x" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 - name: Install Chrome run: sudo apt-get install -y google-chrome-stable - name: Install Selenium @@ -66,14 +80,10 @@ jobs: mkdir bin curl -O https://chromedriver.storage.googleapis.com/`curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip unzip chromedriver_linux64.zip -d bin - - uses: actions/checkout@v3 - - name: Install dependencies - run: | - python -m pip install --upgrade pip setuptools wheel codecov - pip install -e .[test] - pip install django~="${{ matrix.django-version }}.0" - - name: Run tests - run: PATH=$PATH:$(pwd)/bin pytest - - run: codecov - env: - CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} + - uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - run: python -m pip install Django + - run: python -m pip install -e .[test,selenium] + - run: python -m pytest + - uses: codecov/codecov-action@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de592fa6..12bfe59f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,13 +11,11 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.10" - - name: Install Python dependencies - run: python -m pip install --upgrade pip setuptools wheel twine + python-version: "3.x" + - run: python -m pip install --upgrade pip build wheel twine - name: Build dist packages - run: python setup.py sdist bdist_wheel - - name: Upload packages - run: python -m twine upload dist/* + run: python -m build --sdist --wheel + - run: python -m twine upload dist/* env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} @@ -29,7 +27,7 @@ jobs: - uses: actions/setup-node@v3.4.1 - uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.x" - run: python set_version.py - name: Upload packages run: npm publish diff --git a/setup.cfg b/setup.cfg index c23691a0..f02b95dc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,13 +32,6 @@ install_requires = django-appconf>=0.6.0 setup_requires = setuptools_scm - sphinx - pytest-runner -tests_require = - pytest - pytest-cov - pytest-django - selenium [options.extras_require] test = @@ -46,6 +39,8 @@ test = pytest-cov pytest-django selenium +selenium = + selenium docs = sphinx From a96ad8e27c100967066255a020f78e602baf382e Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Fri, 9 Sep 2022 15:54:14 +0200 Subject: [PATCH 071/165] Simplify GH action version setup --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2b2b8f4..f4ee680a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3.4.1 + - uses: actions/setup-node@v3 with: node-version: '12.x' - run: npm install -g standard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 12bfe59f..f8e3b587 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3.4.1 + - uses: actions/setup-node@v3 - uses: actions/setup-python@v4 with: python-version: "3.x" From f5ebb24f3eb8105959a9f77d20d41c110d356346 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 05:08:18 +0000 Subject: [PATCH 072/165] Bump codecov/codecov-action from 2 to 3 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 2 to 3. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v2...v3) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4ee680a..ff5413ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,7 +61,7 @@ jobs: - run: python -m pip install Django~="${{ matrix.django-version }}.0" - run: python -m pip install -e .[test] - run: python -m pytest - - uses: codecov/codecov-action@v2 + - uses: codecov/codecov-action@v3 Selenium: needs: @@ -86,4 +86,4 @@ jobs: - run: python -m pip install Django - run: python -m pip install -e .[test,selenium] - run: python -m pytest - - uses: codecov/codecov-action@v2 + - uses: codecov/codecov-action@v3 From 1f6ac37964a83ff392d51e240d6de9ff00bed413 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Fri, 14 Oct 2022 10:30:47 +0200 Subject: [PATCH 073/165] Add tidelift security information --- SECURITY.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..b0208c5f --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security + +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. From a2fa381ac7ae560d9fa801b26370866e8c6161f8 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 22 Oct 2022 11:10:20 +0200 Subject: [PATCH 074/165] Add tidelift funding link --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index ae3c5338..da739aec 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,3 @@ github: codingjoe +tidelift: pypi/django-select2 custom: https://paypal.me/codingjoe From 7215346187573907b860220dbe0640f2c7776a0c Mon Sep 17 00:00:00 2001 From: Karl Date: Fri, 5 Aug 2022 15:31:43 -0700 Subject: [PATCH 075/165] Add clarification about widget types Help users save time in the event that they're trying to use these extra features with a light widget where it will not work. --- docs/extra.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/extra.rst b/docs/extra.rst index c3524ce7..0865d77c 100644 --- a/docs/extra.rst +++ b/docs/extra.rst @@ -8,6 +8,9 @@ Suppose you have an address form where a user should choose a Country and a City When the user selects a country we want to show only cities belonging to that country. So the one selector depends on another one. +.. note:: + Does not work with the 'light' version (django_select2.forms.Select2Widget). + Models `````` From 5a635feba14b180c6d4821c2e56e6b518c8e921a Mon Sep 17 00:00:00 2001 From: N1K1TAS95 <46042802+N1K1TAS95@users.noreply.github.com> Date: Sun, 30 Oct 2022 23:02:05 +0100 Subject: [PATCH 076/165] Resolve #159 -- Add custom JSONEncoder support via setting (#160) --- django_select2/conf.py | 8 ++++++++ django_select2/views.py | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/django_select2/conf.py b/django_select2/conf.py index 8862932a..a3117014 100644 --- a/django_select2/conf.py +++ b/django_select2/conf.py @@ -198,6 +198,14 @@ class Select2Conf(AppConf): ``settings.DJANGO_SELECT2_I18N`` refers to :attr:`.I18N_PATH`. """ + JSON_ENCODER = 'django.core.serializers.json.DjangoJSONEncoder' + """ + A :class:`JSONEncoder` used to generate the API response for the model widgets. + + A custom JSON encoder might be useful when your models uses + a special primary key, that isn't serializable by the default encoder. + """ + class Meta: """Prefix for all Django-Select2 settings.""" diff --git a/django_select2/views.py b/django_select2/views.py index c03f683e..0af69b64 100644 --- a/django_select2/views.py +++ b/django_select2/views.py @@ -3,6 +3,7 @@ from django.core.signing import BadSignature from django.http import Http404, JsonResponse from django.views.generic.list import BaseListView +from django.utils.module_loading import import_string from .cache import cache from .conf import settings @@ -43,7 +44,8 @@ def get(self, request, *args, **kwargs): for obj in context["object_list"] ], "more": context["page_obj"].has_next(), - } + }, + encoder=import_string(settings.SELECT2_JSON_ENCODER) ) def get_queryset(self): From d410f22254a0761f1af583ef4d0d80765279084e Mon Sep 17 00:00:00 2001 From: Kevin Ramirez Date: Thu, 3 Nov 2022 01:56:00 -0600 Subject: [PATCH 077/165] Fix #79 -- Clear values of related fields (#137) Co-authored-by: Kevin Ramirez --- django_select2/static/django_select2/django_select2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_select2/static/django_select2/django_select2.js b/django_select2/static/django_select2/django_select2.js index 200534ba..f2358df0 100644 --- a/django_select2/static/django_select2/django_select2.js +++ b/django_select2/static/django_select2/django_select2.js @@ -59,7 +59,7 @@ } $element.on('select2:select', function (e) { var name = $(e.currentTarget).attr('name') - $('[data-select2-dependent-fields=' + name + ']').each(function () { + $('[data-select2-dependent-fields~=' + name + ']').each(function () { $(this).val('').trigger('change') }) }) From b568368cb68045db772a3166f1cf80804d096202 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Thu, 3 Nov 2022 16:28:58 +0100 Subject: [PATCH 078/165] Add header image --- README.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 11f5f469..81cf3e09 100644 --- a/README.rst +++ b/README.rst @@ -1,12 +1,12 @@ +|header| + ============== Django-Select2 ============== |version| |coverage| |license| -This is a `Django`_ integration of `Select2`_. - -The app includes Select2 driven Django Widgets. +Custom autocompelte fields for `Django`_. Documentation ------------- @@ -22,6 +22,7 @@ Documentation available at https://django-select2.readthedocs.io/. .. _Select2: https://select2.org/ .. _autocomplete_fields: https://docs.djangoproject.com/en/stable/ref/contrib/admin/#django.contrib.admin.ModelAdmin.autocomplete_fields +.. |header| image:: https://repository-images.githubusercontent.com/266545281/c6db7d26-9f60-454b-845e-395d45c43fa7 .. |version| image:: https://img.shields.io/pypi/v/Django-Select2.svg :target: https://pypi.python.org/pypi/Django-Select2/ .. |coverage| image:: https://codecov.io/gh/codingjoe/django-select2/branch/master/graph/badge.svg From e62b8ea7e86aad3efd8f586f8836c3c28f8678ce Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 5 Nov 2022 12:04:55 +0100 Subject: [PATCH 079/165] Add selenium test marker to stablize CI suite --- .github/workflows/ci.yml | 4 ++-- tests/conftest.py | 5 +++++ tests/test_forms.py | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff5413ab..ddd59a2e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: python-version: ${{ matrix.python-version }} - run: python -m pip install Django~="${{ matrix.django-version }}.0" - run: python -m pip install -e .[test] - - run: python -m pytest + - run: python -m pytest -m "not selenium" - uses: codecov/codecov-action@v3 Selenium: @@ -85,5 +85,5 @@ jobs: python-version: ${{ matrix.python-version }} - run: python -m pip install Django - run: python -m pip install -e .[test,selenium] - - run: python -m pytest + - run: python -m pytest -m selenium - uses: codecov/codecov-action@v3 diff --git a/tests/conftest.py b/tests/conftest.py index b5e37416..3ac31e51 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,6 +6,11 @@ from selenium.common.exceptions import WebDriverException +def pytest_configure(config): + config.addinivalue_line( + "markers", "selenium: skip if selenium is not installed" + ) + def random_string(n): return "".join( random.choice(string.ascii_uppercase + string.digits) for _ in range(n) diff --git a/tests/test_forms.py b/tests/test_forms.py index 70a89d55..6e81f50b 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -82,12 +82,14 @@ def test_allow_clear(self, db): "primary_genre", None ) + @pytest.mark.selenium def test_no_js_error(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): error = driver.find_element(By.XPATH, "//body[@JSError]") pytest.fail(error.get_attribute("JSError")) + @pytest.mark.selenium def test_selecting(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): @@ -298,6 +300,7 @@ def test_many_selected_option(self, db, genres): ), widget_output assert selected_option2 in widget_output or selected_option2a in widget_output + @pytest.mark.selenium def test_multiple_widgets(self, db, live_server, driver): driver.get(live_server + self.url) with pytest.raises(NoSuchElementException): @@ -641,6 +644,7 @@ class TestHeavySelect2MultipleWidget: bool(os.environ.get("CI", False)), reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=1772", ) + @pytest.mark.selenium def test_widgets_selected_after_validation_error(self, db, live_server, driver): driver.get(live_server + self.url) WebDriverWait(driver, 3).until( @@ -678,6 +682,7 @@ class TestAddressChainedSelect2Widget: url = reverse("model_chained_select2_widget") form = forms.AddressChainedSelect2WidgetForm() + @pytest.mark.selenium def test_widgets_selected_after_validation_error( self, db, live_server, driver, countries, cities ): @@ -757,6 +762,7 @@ def test_widgets_selected_after_validation_error( assert len(country_names_from_browser) != Country.objects.count() assert country_names_from_browser == country_names_from_db + @pytest.mark.selenium def test_dependent_fields_clear_after_change_parent( self, db, live_server, driver, countries, cities ): From cc834af3934488c1e98f8fc483835f00b5d10e9d Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 5 Nov 2022 12:08:58 +0100 Subject: [PATCH 080/165] Repleace fussyfox with GH actions --- .fussyfox.yml | 5 ----- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ linter-requirements.txt | 5 +++++ 3 files changed, 27 insertions(+), 5 deletions(-) delete mode 100644 .fussyfox.yml create mode 100644 linter-requirements.txt diff --git a/.fussyfox.yml b/.fussyfox.yml deleted file mode 100644 index 6a17e6bd..00000000 --- a/.fussyfox.yml +++ /dev/null @@ -1,5 +0,0 @@ -- bandit -- black -- flake8 -- isort -- pydocstyle diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ddd59a2e..042d813a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,26 @@ on: jobs: + lint: + runs-on: ubuntu-latest + strategy: + matrix: + lint-command: + - bandit -r . -x ./tests + - black --check --diff . + - flake8 . + - isort --check-only --diff . + - pydocstyle . + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + cache: 'pip' + cache-dependency-path: 'linter-requirements.txt' + - run: python -m pip install -r linter-requirements.txt + - run: ${{ matrix.lint-command }} + dist: runs-on: ubuntu-latest steps: @@ -41,6 +61,7 @@ jobs: PyTest: needs: + - lint - standardjs strategy: matrix: @@ -65,6 +86,7 @@ jobs: Selenium: needs: + - lint - standardjs strategy: matrix: diff --git a/linter-requirements.txt b/linter-requirements.txt new file mode 100644 index 00000000..c3083bcb --- /dev/null +++ b/linter-requirements.txt @@ -0,0 +1,5 @@ +bandit==1.7.4 +black==22.10.0 +flake8==5.0.4 +isort==5.10.1 +pydocstyle[toml]==6.1.1 From 5894b52ea7303fde4fb58c23172f5240d89a2aef Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 5 Nov 2022 12:10:00 +0100 Subject: [PATCH 081/165] Reformat code using black & isort --- django_select2/conf.py | 2 +- django_select2/views.py | 4 ++-- tests/conftest.py | 5 ++--- tests/test_forms.py | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/django_select2/conf.py b/django_select2/conf.py index a3117014..03ebe7dd 100644 --- a/django_select2/conf.py +++ b/django_select2/conf.py @@ -198,7 +198,7 @@ class Select2Conf(AppConf): ``settings.DJANGO_SELECT2_I18N`` refers to :attr:`.I18N_PATH`. """ - JSON_ENCODER = 'django.core.serializers.json.DjangoJSONEncoder' + JSON_ENCODER = "django.core.serializers.json.DjangoJSONEncoder" """ A :class:`JSONEncoder` used to generate the API response for the model widgets. diff --git a/django_select2/views.py b/django_select2/views.py index 0af69b64..1665dbd5 100644 --- a/django_select2/views.py +++ b/django_select2/views.py @@ -2,8 +2,8 @@ from django.core import signing from django.core.signing import BadSignature from django.http import Http404, JsonResponse -from django.views.generic.list import BaseListView from django.utils.module_loading import import_string +from django.views.generic.list import BaseListView from .cache import cache from .conf import settings @@ -45,7 +45,7 @@ def get(self, request, *args, **kwargs): ], "more": context["page_obj"].has_next(), }, - encoder=import_string(settings.SELECT2_JSON_ENCODER) + encoder=import_string(settings.SELECT2_JSON_ENCODER), ) def get_queryset(self): diff --git a/tests/conftest.py b/tests/conftest.py index 3ac31e51..60bbe399 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,9 +7,8 @@ def pytest_configure(config): - config.addinivalue_line( - "markers", "selenium: skip if selenium is not installed" - ) + config.addinivalue_line("markers", "selenium: skip if selenium is not installed") + def random_string(n): return "".join( diff --git a/tests/test_forms.py b/tests/test_forms.py index 6e81f50b..621a24e1 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -20,8 +20,8 @@ HeavySelect2Widget, ModelSelect2TagWidget, ModelSelect2Widget, - Select2Widget, Select2AdminMixin, + Select2Widget, ) from tests.testapp import forms from tests.testapp.forms import ( From 10d5e8d681fc0bd38b3520e3f51bbd7fb9eeafac Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 5 Nov 2022 11:50:59 +0100 Subject: [PATCH 082/165] Fix #163 -- Lazily get i18n locale name A widget instance can leak the i18n setting to another request or be stuck on the default language setting. --- django_select2/forms.py | 7 ++++--- tests/test_forms.py | 25 ++++++++++++++----------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index df3982fe..5e2ea5fd 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -86,9 +86,10 @@ class Select2Mixin: empty_label = "" - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.i18n_name = SELECT2_TRANSLATIONS.get(get_language()) + @property + def i18n_name(self): + """Name of the i18n file for the current language.""" + return SELECT2_TRANSLATIONS.get(get_language()) def build_attrs(self, base_attrs, extra_attrs=None): """Add select2 data attributes.""" diff --git a/tests/test_forms.py b/tests/test_forms.py index 621a24e1..4e148f7a 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -3,7 +3,6 @@ from collections.abc import Iterable import pytest -from django.contrib.admin.widgets import SELECT2_TRANSLATIONS from django.db.models import QuerySet from django.urls import reverse from django.utils import translation @@ -48,11 +47,16 @@ def test_initial_form_class(self): assert "my-class" in widget.render("name", None) assert "django-select2" in widget.render("name", None) - @pytest.mark.parametrize("code,name", SELECT2_TRANSLATIONS.items()) - def test_lang_attr(self, code, name): - translation.activate(code) - widget = self.widget_cls() - assert f'lang="{name}"' in widget.render("name", None) + def test_lang_attr(self): + with translation.override("de"): + widget = Select2Widget() + assert 'lang="de"' in widget.render("name", None) + + # Regression test for #163 + widget = Select2Widget() + assert widget.i18n_name == "en" + with translation.override("de"): + assert widget.i18n_name == "de" def test_allow_clear(self, db): required_field = self.form.fields["artist"] @@ -258,11 +262,10 @@ def test_initial_form_class(self): "name", None ) - @pytest.mark.parametrize("code,name", SELECT2_TRANSLATIONS.items()) - def test_lang_attr(self, code, name): - translation.activate(code) - widget = self.widget_cls(data_view="heavy_data_1") - assert f'lang="{name}"' in widget.render("name", None) + def test_lang_attr(self): + with translation.override("fr"): + widget = self.widget_cls(data_view="heavy_data_1") + assert 'lang="fr"' in widget.render("name", None) def test_selected_option(self, db): not_required_field = self.form.fields["primary_genre"] From 15790a3dd54f66cd03879497f5016052cf4da9b1 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 5 Nov 2022 13:38:41 +0100 Subject: [PATCH 083/165] Update packaging to pyproject.toml --- .editorconfig | 2 +- .github/workflows/ci.yml | 4 +- .github/workflows/release.yml | 1 + .gitignore | 2 + LICENSE | 2 +- django_select2/__init__.py | 5 ++ pyproject.toml | 89 +++++++++++++++++++++++++++++++++++ set_version.py | 5 +- setup.cfg | 85 +-------------------------------- setup.py | 5 -- 10 files changed, 105 insertions(+), 95 deletions(-) create mode 100644 pyproject.toml delete mode 100755 setup.py diff --git a/.editorconfig b/.editorconfig index f69b8ec1..d7e0de91 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,7 +10,7 @@ insert_final_newline = true charset = utf-8 end_of_line = lf -[*.{json,yml,yaml,js,jsx}] +[*.{json,yml,yaml,js,jsx,toml}] indent_size = 2 [LICENSE] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 042d813a..bc44000f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,8 +34,8 @@ jobs: - uses: actions/setup-python@v4 with: python-version: "3.x" - - run: python -m pip install --upgrade pip setuptools wheel twine readme-renderer - - run: python setup.py sdist bdist_wheel + - run: python -m pip install --upgrade pip build wheel twine readme-renderer + - run: python -m build --sdist --wheel - run: python -m twine check dist/* standardjs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f8e3b587..f6548af4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,6 +28,7 @@ jobs: - uses: actions/setup-python@v4 with: python-version: "3.x" + - run: python -m pip install --upgrade setuptools_scm - run: python set_version.py - name: Upload packages run: npm publish diff --git a/.gitignore b/.gitignore index d1ef58f6..8c43d48c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ ghostdriver.log coverage.xml .eggs/ db.sqlite3 + +_version.py diff --git a/LICENSE b/LICENSE index d5d8ec80..3f28e2b7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Johannes Hoppe +Copyright (c) 2022 Johannes Maron Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/django_select2/__init__.py b/django_select2/__init__.py index 575a0213..95783ce7 100644 --- a/django_select2/__init__.py +++ b/django_select2/__init__.py @@ -9,5 +9,10 @@ """ from django import get_version +from . import _version + +__version__ = _version.version +VERSION = _version.version_tuple + if get_version() < "3.2": default_app_config = "django_select2.apps.Select2AppConfig" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..1d4fb2f5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,89 @@ +[build-system] +requires = ["flit_core>=3.2", "flit_scm", "wheel"] +build-backend = "flit_scm:buildapi" + +[project] +name = "django-select2" +authors = [ + { name = "Johannes Maron", email = "johannes@maron.family" }, +] +readme = "README.rst" +license = { file = "LICENSE" } +keywords = ["Django", "select2", "autocomplete", "typeahead"] +dynamic = ["version", "description"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: MIT License", + "Intended Audience :: Developers", + "Environment :: Web Environment", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Framework :: Django", + "Framework :: Django :: 3.2", + "Framework :: Django :: 4.0", + "Framework :: Django :: 4.1", + "Topic :: Software Development", +] +requires-python = ">=3.8" +dependencies = [ + "django>=3.2", + "django-appconf>=0.6.0" +] + +[project.optional-dependencies] +test = [ + "pytest", + "pytest-cov", + "pytest-django", + "selenium", +] +selenium = [ + "selenium", +] +docs = [ + "sphinx", +] + +[project.urls] +Project-URL = "https://github.com/codingjoe/django-select2" +Changelog = "https://github.com/codingjoe/django-select2/releases" +Source = "https://github.com/codingjoe/django-select2" +Documentation = "https://django-select2.rtfd.io/" +Issue-Tracker = "https://github.com/codingjoe/django-select2/issues" + +[tool.flit.module] +name = "django_select2" + +[tool.setuptools_scm] +write_to = "django_select2/_version.py" + +[tool.pytest.ini_options] +minversion = "6.0" +addopts = "--cov --tb=short -rxs" +testpaths = ["tests"] +DJANGO_SETTINGS_MODULE = "tests.testapp.settings" + +[tool.coverage.run] +source = ["django_select2"] + +[tool.coverage.report] +show_missing = true + +[tool.isort] +atomic = true +line_length = 88 +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true +known_first_party = "django_select2, tests" +default_section = "THIRDPARTY" +combine_as_imports = true + +[tool.pydocstyle] +add_ignore = "D1" diff --git a/set_version.py b/set_version.py index 50ffa7bf..fa18ce33 100755 --- a/set_version.py +++ b/set_version.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 """Set the version in NPM's package.json to match the git tag.""" import json -import os + +from setuptools_scm import get_version if __name__ == "__main__": with open("package.json", "r+") as f: data = json.load(f) f.seek(0) - data["version"] = os.environ["GITHUB_REF"].rsplit("/")[-1] + data["version"] = get_version(root=".", relative_to=__file__) json.dump(data, f) f.truncate() diff --git a/setup.cfg b/setup.cfg index f02b95dc..6f60592c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,87 +1,4 @@ -[metadata] -name = django-select2 -author = Johannes Hoppe -author_email = info@johanneshoppe.com -description = Select2 option fields for Django -long_description = file: README.rst -url = https://github.com/codingjoe/django-select2 -license = MIT -license_file = LICENSE -classifier = - Development Status :: 5 - Production/Stable - Environment :: Web Environment - Intended Audience :: Developers - License :: OSI Approved :: Apache Software License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Framework :: Django - Framework :: Django :: 3.2 - Framework :: Django :: 4.0 - Framework :: Django :: 4.1 - -[options] -include_package_data = True -packages = django_select2 -install_requires = - django>=3.2 - django-appconf>=0.6.0 -setup_requires = - setuptools_scm - -[options.extras_require] -test = - pytest - pytest-cov - pytest-django - selenium -selenium = - selenium -docs = - sphinx - -[bdist_wheel] -universal = 1 - -[bdist_rpm] -requires = - python-django-appconf >= 2.0 - -[aliases] -test = pytest - -[build_sphinx] -source-dir = docs -build-dir = docs/_build - -[tool:pytest] -addopts = - tests - --doctest-glob='*.rst' - --doctest-modules - --cov=django_select2 -DJANGO_SETTINGS_MODULE=tests.testapp.settings - [flake8] max-line-length=88 select = C,E,F,W,B,B950 -ignore = E203, E501, W503 -exclude = venv,.tox,.eggs - -[pydocstyle] -add-ignore = D1 - -[isort] -atomic = true -line_length = 88 -multi_line_output = 3 -include_trailing_comma = True -force_grid_wrap = 0 -use_parentheses = True -known_first_party = django_select2, tests -default_section = THIRDPARTY -combine_as_imports = true +ignore = E203, E501, W503, E731 diff --git a/setup.py b/setup.py deleted file mode 100755 index f4bd8e57..00000000 --- a/setup.py +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup - -setup(name="django-select2", use_scm_version=True) From 3781b67ffd4128585bcf99312f22c92e42d3e04c Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 5 Nov 2022 14:24:59 +0100 Subject: [PATCH 084/165] Fix Select2AdminMixin --- django_select2/forms.py | 5 +++-- tests/test_forms.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/django_select2/forms.py b/django_select2/forms.py index 5e2ea5fd..68be213f 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -146,14 +146,15 @@ 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): + css = {**AutocompleteMixin(None, None).media._css} + css["screen"].append("django_select2/django_select2.css") return forms.Media( js=Select2Mixin().media._js, - css=AutocompleteMixin(None, None).media._css, + css=css, ) diff --git a/tests/test_forms.py b/tests/test_forms.py index 4e148f7a..0b7c0af7 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -195,6 +195,7 @@ def test_media(self): "screen": [ "admin/css/vendor/select2/select2.min.css", "admin/css/autocomplete.css", + "django_select2/django_select2.css", ] } From 112846cc76fa137a3946a2e71425deb9a561aa58 Mon Sep 17 00:00:00 2001 From: Johannes Maron Date: Sat, 5 Nov 2022 17:42:11 +0100 Subject: [PATCH 085/165] Change default Select2 version to Django's vendored version --- django_select2/conf.py | 75 +++---------------- django_select2/forms.py | 4 +- .../static/django_select2/django_select2.js | 2 +- django_select2/views.py | 2 +- docs/extra.rst | 8 +- docs/index.rst | 18 ++++- example/example/settings.py | 6 +- .../example/templates/example/book_form.html | 4 +- example/requirements.txt | 2 +- tests/test_forms.py | 39 ++++------ tests/testapp/settings.py | 1 + tests/testapp/templates/form.html | 7 +- 12 files changed, 56 insertions(+), 112 deletions(-) diff --git a/django_select2/conf.py b/django_select2/conf.py index 03ebe7dd..0f34f774 100644 --- a/django_select2/conf.py +++ b/django_select2/conf.py @@ -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. @@ -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/%7Bversion%7D/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:: @@ -76,11 +73,9 @@ class Select2Conf(AppConf): develop without an Internet connection. """ - CSS = "https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bversion%7D/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:: @@ -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/%7Bversion%7D/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:: @@ -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. diff --git a/django_select2/forms.py b/django_select2/forms.py index 68be213f..4809d066 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -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. @@ -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): """ diff --git a/django_select2/static/django_select2/django_select2.js b/django_select2/static/django_select2/django_select2.js index f2358df0..01db20b5 100644 --- a/django_select2/static/django_select2/django_select2.js +++ b/django_select2/static/django_select2/django_select2.js @@ -6,7 +6,7 @@ module.exports = factory(require('jquery')) } else { // Browser globals - factory(jQuery) + factory(jQuery || window.django.jQuery) } }(function ($) { 'use strict' diff --git a/django_select2/views.py b/django_select2/views.py index 1665dbd5..66fdc420 100644 --- a/django_select2/views.py +++ b/django_select2/views.py @@ -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") diff --git a/docs/extra.rst b/docs/extra.rst index 0865d77c..4de25275 100644 --- a/docs/extra.rst +++ b/docs/extra.rst @@ -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'], @@ -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'], @@ -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'}, @@ -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'}, diff --git a/docs/index.rst b/docs/index.rst index 6ba1f8f3..35454f9c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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: @@ -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 diff --git a/example/example/settings.py b/example/example/settings.py index 7e629a6e..6eef77a3 100644 --- a/example/example/settings.py +++ b/example/example/settings.py @@ -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"}, }, } diff --git a/example/example/templates/example/book_form.html b/example/example/templates/example/book_form.html index c2ff60bf..daea5304 100644 --- a/example/example/templates/example/book_form.html +++ b/example/example/templates/example/book_form.html @@ -1,4 +1,4 @@ - +{% load static %} Create Book @@ -14,7 +14,7 @@

Create a new Book

{{ form.as_p }} - + {{ form.media.js }} diff --git a/example/requirements.txt b/example/requirements.txt index 53500ba2..b93550d1 100644 --- a/example/requirements.txt +++ b/example/requirements.txt @@ -1,2 +1,2 @@ -e .. -django-redis +redis diff --git a/tests/test_forms.py b/tests/test_forms.py index 0b7c0af7..a3a0d8b5 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -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, @@ -135,28 +134,28 @@ 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/%7Bsettings.SELECT2_LIB_VERSION%7D/js/select2.min.js", - f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/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/%7Bsettings.SELECT2_LIB_VERSION%7D/js/select2.min.js", - f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/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/%7Bsettings.SELECT2_LIB_VERSION%7D/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/%7Bsettings.SELECT2_LIB_VERSION%7D/js/select2.min.js", - f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/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", ) @@ -164,15 +163,15 @@ def test_i18n(self): translation.activate("zh-hans") assert tuple(Select2Widget().media._js) == ( - f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/js/select2.min.js", - f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/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/%7Bsettings.SELECT2_LIB_VERSION%7D/js/select2.min.js", - f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/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", ) @@ -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/%7Bsettings.SELECT2_LIB_VERSION%7D/js/select2.min.js", - f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/js/i18n/en.js", + "admin/js/vendor/select2/select2.full.min.js", + "admin/js/vendor/select2/i18n/en.js", "django_select2/django_select2.js", ) @@ -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/%7Bsettings.SELECT2_LIB_VERSION%7D/js/select2.min.js" - in result - ) - assert ( - f"https://cdnjs.cloudflare.com/ajax/libs/select2/%7Bsettings.SELECT2_LIB_VERSION%7D/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): diff --git a/tests/testapp/settings.py b/tests/testapp/settings.py index 15b29b59..f6673aa9 100644 --- a/tests/testapp/settings.py +++ b/tests/testapp/settings.py @@ -12,6 +12,7 @@ "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.staticfiles", + "django.contrib.admin", "django_select2", "tests.testapp", ) diff --git a/tests/testapp/templates/form.html b/tests/testapp/templates/form.html index 7499bc8e..bd817eb2 100644 --- a/tests/testapp/templates/form.html +++ b/tests/testapp/templates/form.html @@ -1,6 +1,5 @@ -{% load static %} - - +{% load static %} + {{ form.media.css }}