From 71b8c038919f21e81076d7b5d64514e4d1c39cca Mon Sep 17 00:00:00 2001 From: Josh Yu Date: Mon, 11 Mar 2024 07:14:40 +0000 Subject: [PATCH] feat: add django 4.2 support, python 3.10 support, remove django 3.1 support --- .github/workflows/lint.yml | 6 ++--- .github/workflows/test.yml | 15 ++++++----- CHANGELOG.rst | 2 ++ aldryn_redirects/admin.py | 38 +++++++++++++++------------ aldryn_redirects/forms.py | 1 + aldryn_redirects/models.py | 10 ++++--- aldryn_redirects/validators.py | 1 + setup.cfg | 43 +++++++++++++++++++++++++++++++ setup.py | 1 + tests/requirements/dj22_cms40.txt | 5 ---- tests/requirements/dj42_cms40.txt | 5 ++++ tests/settings.py | 1 + tests/test_admin.py | 6 +++-- tests/test_forms.py | 5 ++-- tox.ini | 30 +++++++++++++-------- 15 files changed, 119 insertions(+), 50 deletions(-) create mode 100644 setup.cfg delete mode 100644 tests/requirements/dj22_cms40.txt create mode 100644 tests/requirements/dj42_cms40.txt diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 63fc275..7154bc3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - name: Install flake8 run: pip install --upgrade flake8 - name: Run flake8 @@ -29,10 +29,10 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - run: python -m pip install isort - name: isort uses: liskin/gh-problem-matcher-wrap@v1 with: linters: isort - run: isort -c -rc -df ./ \ No newline at end of file + run: isort --check-only --diff ./ \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 47a719a..8041dd6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,18 +8,22 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ 3.7, 3.8, 3.9 ] # latest release minus two + python-version: [ 3.8, 3.9, '3.10' ] requirements-file: [ - dj22_cms40.txt, dj32_cms40.txt, + dj42_cms40.txt, ] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: 'tests/requirements/*.txt' + - name: Install dependencies run: | python -m pip install --upgrade pip @@ -27,6 +31,3 @@ jobs: python setup.py install - name: Run coverage run: coverage run setup.py test - - - name: Upload Coverage to Codecov - uses: codecov/codecov-action@v1 \ No newline at end of file diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 050a3c3..6288aa3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,8 @@ Changelog Unreleased ========== +* Introduced Django 4.2 support. +* Dropped Support for Django<3.1 1.0.2 (2023-02-24) ================== diff --git a/aldryn_redirects/admin.py b/aldryn_redirects/admin.py index e5e5858..71d11ee 100644 --- a/aldryn_redirects/admin.py +++ b/aldryn_redirects/admin.py @@ -1,24 +1,33 @@ -from aldryn_translation_tools.admin import AllTranslationsMixin from django.conf import settings from django.contrib import admin, messages from django.http import HttpResponse from django.shortcuts import redirect, render from django.urls import reverse from django.utils import timezone -from django.utils.translation import gettext -from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext, gettext_lazy as _ + +from aldryn_translation_tools.admin import AllTranslationsMixin from parler.admin import TranslatableAdmin from tablib import Dataset -from .forms import (RedirectsImportForm, StaticRedirectForm, - StaticRedirectsImportForm) -from .models import (Redirect, StaticRedirect, - StaticRedirectInboundRouteQueryParam) +from .forms import ( + RedirectsImportForm, + StaticRedirectForm, + StaticRedirectsImportForm, +) +from .models import ( + Redirect, + StaticRedirect, + StaticRedirectInboundRouteQueryParam, +) class DeletionMixin(): actions = ['delete_selected'] + @admin.action( + description=_('Delete selected objects') + ) def delete_selected(self, request, queryset): max_items_deletion = getattr(settings, 'DATA_UPLOAD_MAX_NUMBER_FIELDS', 1000) # COMPAT: Django<1.10 @@ -35,9 +44,9 @@ def delete_selected(self, request, queryset): object_label = self.opts.verbose_name_plural if deleted_qty > 1 else self.opts.verbose_name msg = _('Successfully deleted {qty} {object_label}.').format(qty=deleted_qty, object_label=object_label) self.message_user(request, msg) - delete_selected.short_description = _('Delete selected objects') +@admin.register(Redirect) class RedirectAdmin(DeletionMixin, AllTranslationsMixin, TranslatableAdmin): list_display = ('old_path',) list_filter = ('site',) @@ -47,12 +56,12 @@ class RedirectAdmin(DeletionMixin, AllTranslationsMixin, TranslatableAdmin): export_headers = ['Domain', 'Old', 'New', 'Language'] def get_urls(self): - from django.conf.urls import url + from django.urls import re_path def pattern(regex, fn, name): args = [regex, self.admin_site.admin_view(fn)] url_name = "%s_%s_%s" % (self.opts.app_label, self.opts.model_name, name) - return url(*args, name=url_name) + return re_path(*args, name=url_name) url_patterns = [ pattern(r'export/$', self.export_view, 'export'), @@ -130,6 +139,7 @@ class StaticRedirectInboundRouteQueryParamInline(admin.TabularInline): extra = 1 +@admin.register(StaticRedirect) class StaticRedirectAdmin(DeletionMixin, admin.ModelAdmin): inlines = [StaticRedirectInboundRouteQueryParamInline] filter_horizontal = ('sites',) @@ -143,12 +153,12 @@ class StaticRedirectAdmin(DeletionMixin, admin.ModelAdmin): export_headers = ['domain', 'inbound_route', 'outbound_route'] def get_urls(self): - from django.conf.urls import url + from django.urls import re_path def pattern(regex, fn, name): args = [regex, self.admin_site.admin_view(fn)] url_name = "%s_%s_%s" % (self.opts.app_label, self.opts.model_name, name) - return url(*args, name=url_name) + return re_path(*args, name=url_name) url_patterns = [ pattern(r'export/$', self.export_view, 'export'), @@ -215,7 +225,3 @@ def import_view(self, request): 'errors': form.errors, } return render(request, 'admin/aldryn_redirects/staticredirect/import_form.html', context) - - -admin.site.register(Redirect, RedirectAdmin) -admin.site.register(StaticRedirect, StaticRedirectAdmin) diff --git a/aldryn_redirects/forms.py b/aldryn_redirects/forms.py index 717ccb7..81bf85b 100644 --- a/aldryn_redirects/forms.py +++ b/aldryn_redirects/forms.py @@ -1,6 +1,7 @@ from django import forms from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ + from tablib import Dataset from .importers import RedirectImporter, StaticRedirectImporter diff --git a/aldryn_redirects/models.py b/aldryn_redirects/models.py index d7e9e11..0db6854 100644 --- a/aldryn_redirects/models.py +++ b/aldryn_redirects/models.py @@ -1,13 +1,15 @@ from django.contrib.sites.models import Site from django.db import models from django.urls import reverse -from django.utils.translation import gettext -from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext, gettext_lazy as _ + from parler.models import TranslatableModel, TranslatedFields from six.moves.urllib.parse import urljoin, urlparse -from .managers import (StaticRedirectInboundRouteQueryParamManager, - StaticRedirectManager) +from .managers import ( + StaticRedirectInboundRouteQueryParamManager, + StaticRedirectManager, +) from .utils import add_query_params_to_url from .validators import validate_inbound_route, validate_outbound_route diff --git a/aldryn_redirects/validators.py b/aldryn_redirects/validators.py index b0c9f90..121b2da 100644 --- a/aldryn_redirects/validators.py +++ b/aldryn_redirects/validators.py @@ -4,6 +4,7 @@ from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ + from six.moves.urllib.parse import urlparse diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..905a8c3 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,43 @@ +[flake8] +max-line-length = 120 +exclude = + .git, + __pycache__, + **/migrations/, + build/, + .tox/, + +[isort] +line_length = 79 +multi_line_output = 3 +lines_after_imports = 2 +combine_as_imports = true +include_trailing_comma = true +balanced_wrapping = true +skip = manage.py, migrations, .tox +extra_standard_library = mock +known_django = django +known_cms = cms, menus +known_first_party = djangocms_version_locking +sections = FUTURE, STDLIB, DJANGO, CMS, THIRDPARTY, FIRSTPARTY, LOCALFOLDER + +[coverage:run] +branch = True +source = djangocms_version_locking +omit = + *apps.py, + *constants.py, + *migrations/*, + *test_utils/*, + *tests/*, + +[coverage:report] +exclude_lines = + pragma: no cover + def __repr__ + if self.debug: + if settings.DEBUG + raise AssertionError + raise NotImplementedError + if 0: + if __name__ == .__main__.: \ No newline at end of file diff --git a/setup.py b/setup.py index 316cf35..f3a1a72 100644 --- a/setup.py +++ b/setup.py @@ -2,6 +2,7 @@ from aldryn_redirects import __version__ + REQUIREMENTS = [ 'tablib', 'django-parler', diff --git a/tests/requirements/dj22_cms40.txt b/tests/requirements/dj22_cms40.txt deleted file mode 100644 index 3552ea2..0000000 --- a/tests/requirements/dj22_cms40.txt +++ /dev/null @@ -1,5 +0,0 @@ --r ./requirements_base.txt - -Django>=2.2,<3.0 -django-classy-tags<2.0.0 -django-sekizai<2.0.0 \ No newline at end of file diff --git a/tests/requirements/dj42_cms40.txt b/tests/requirements/dj42_cms40.txt new file mode 100644 index 0000000..e49f2b4 --- /dev/null +++ b/tests/requirements/dj42_cms40.txt @@ -0,0 +1,5 @@ +-r ./requirements_base.txt + +Django>=4.2,<5.0 +django-classy-tags +django-sekizai \ No newline at end of file diff --git a/tests/settings.py b/tests/settings.py index 2e29262..c90ff19 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -1,6 +1,7 @@ #!/usr/bin/env python from __future__ import division, print_function + HELPER_SETTINGS = { 'MIDDLEWARE': [ 'django.contrib.sessions.middleware.SessionMiddleware', diff --git a/tests/test_admin.py b/tests/test_admin.py index 6ed6c36..b342cad 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -1,9 +1,11 @@ import re -from bs4 import BeautifulSoup +from django.shortcuts import reverse + from cms.models import Site from cms.test_utils.testcases import CMSTestCase -from django.shortcuts import reverse + +from bs4 import BeautifulSoup from aldryn_redirects.models import Redirect, StaticRedirect diff --git a/tests/test_forms.py b/tests/test_forms.py index 54b9b7d..78f05ab 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -1,8 +1,9 @@ -from cms.test_utils.testcases import CMSTestCase -from cms.utils import get_current_site from django.contrib.sites.models import Site from django.core.exceptions import ValidationError +from cms.test_utils.testcases import CMSTestCase +from cms.utils import get_current_site + from aldryn_redirects.forms import StaticRedirectForm from aldryn_redirects.models import StaticRedirect diff --git a/tox.ini b/tox.ini index 4bcd2c5..ad5d033 100644 --- a/tox.ini +++ b/tox.ini @@ -1,26 +1,34 @@ [tox] envlist = flake8 - py{36,35,27}-dj{18,19,110,111}-cms{34,33} + py{38,39,310}-dj{32,42}-sqlite-cms40 skip_missing_interpreters=True [testenv] deps = - -r{toxinidir}/tests/requirements.txt - dj18: Django>=1.8,<1.9 - dj19: Django>=1.9,<1.10 - dj110: Django>=1.10,<1.11 - dj111: Django>=1.11,<1.12 - cms33: django-cms>=3.3,<3.4 - cms34: django-cms>=3.4,<3.5 + flake8: -r{toxinidir}/tests/requirements/requirements_base.txt + isort: -r{toxinidir}/tests/requirements/requirements_base.txt + + dj32: -r{toxinidir}/tests/requirements/dj32_cms40.txt + dj42: -r{toxinidir}/tests/requirements/dj42_cms40.txt + +basepython = + py38: python3.8 + py39: python3.9 + py310: python3.10 + commands = {envpython} --version {env:COMMAND:coverage} erase {env:COMMAND:coverage} run setup.py test {env:COMMAND:coverage} report -[flake8] -max-line-length = 120 -exclude = */docs/*,*/migrations/* +[testenv:flake8] +commands = flake8 +basepython = python3.9 + +[testenv:isort] +commands = isort --recursive --check-only --diff {toxinidir} +basepython = python3.9