From 325f3556812b69206a815ffce40352742401f472 Mon Sep 17 00:00:00 2001 From: Aiky30 Date: Fri, 14 Jan 2022 18:00:16 +0000 Subject: [PATCH] feat: Added Django 3.2 and Python 3.8 and 3.9 support (#196) * remove python_2_unicode_compatible * remove file # -*- coding: utf-8 -*- declarations * remove python2 __future__ imports and six primitive types * replaced lru cache imports to: from functools import lru_cache * remapped import for ACTION_CHECKBOX_NAME * replaced ugettext with gettext, ugettext_lazy with gettext_lazy, and ungettext with ngettext * test assertEquals replaced with assertEqual * replaced force_text() with force_str(), https://docs.djangoproject.com/en/3.2/ref/utils/#django.utils.encoding.force_text * moved from django.conf.urls.url() to django.urls.re_path() --- .github/workflows/lint.yml | 4 +- .github/workflows/test.yml | 4 +- .gitignore | 1 + CHANGELOG.rst | 5 ++- djangocms_moderation/admin.py | 45 +++++++++---------- djangocms_moderation/admin_actions.py | 14 +++--- djangocms_moderation/apps.py | 4 +- djangocms_moderation/cms_toolbars.py | 3 +- djangocms_moderation/conf.py | 2 +- djangocms_moderation/constants.py | 4 +- .../contrib/moderation_forms/cms_plugins.py | 2 +- .../migrations/0001_initial.py | 3 -- .../contrib/moderation_forms/models.py | 2 +- djangocms_moderation/emails.py | 8 ++-- djangocms_moderation/filters.py | 10 ++--- djangocms_moderation/forms.py | 10 ++--- djangocms_moderation/handlers.py | 2 - djangocms_moderation/helpers.py | 2 +- djangocms_moderation/managers.py | 2 - .../migrations/0001_initial.py | 3 -- .../migrations/0002_auto_20180905_1152.py | 3 -- .../migrations/0003_auto_20180903_1206.py | 3 -- .../migrations/0004_auto_20180907_1206.py | 3 -- .../migrations/0005_auto_20180919_1348.py | 3 -- .../migrations/0006_auto_20181001_1840.py | 3 -- .../migrations/0007_auto_20181002_1725.py | 3 -- .../migrations/0008_auto_20181002_1833.py | 3 -- .../migrations/0009_auto_20181005_1534.py | 3 -- .../migrations/0010_auto_20181008_1317.py | 3 -- .../migrations/0011_auto_20181008_1328.py | 3 -- .../migrations/0012_auto_20181016_1319.py | 3 -- .../migrations/0013_auto_20181122_1110.py | 3 -- .../migrations/0014_auto_20190313_1638.py | 3 -- .../migrations/0014_auto_20190315_1723.py | 3 -- .../0016_moderationrequesttreenode.py | 3 -- djangocms_moderation/models.py | 15 ++----- djangocms_moderation/monkeypatch.py | 2 +- djangocms_moderation/signals.py | 17 ++----- djangocms_moderation/utils.py | 5 +-- djangocms_moderation/views.py | 6 +-- setup.py | 2 +- tests/requirements/dj11_cms40.txt | 9 ---- tests/requirements/dj22_cms40.txt | 9 ++-- tests/requirements/dj32_cms40.txt | 6 +++ tests/requirements/requirements_base.txt | 9 ++-- tests/settings.py | 2 + tests/test_admin_actions.py | 16 +++---- tests/test_cms_toolbars.py | 2 +- tests/test_models.py | 4 +- tests/test_utils.py | 8 ++-- tox.ini | 27 +++++------ 51 files changed, 112 insertions(+), 202 deletions(-) delete mode 100644 tests/requirements/dj11_cms40.txt create mode 100644 tests/requirements/dj32_cms40.txt diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f541d708..6760a90a 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,7 +29,7 @@ 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 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 63a69058..704336cc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,10 +10,10 @@ jobs: strategy: fail-fast: false matrix: - python-version: [ 3.6, 3.7, 3.8, ] # latest release minus two + python-version: [ 3.7, 3.8, 3.9 ] # latest release minus two requirements-file: [ - dj11_cms40.txt, dj22_cms40.txt, + dj32_cms40.txt, ] os: [ ubuntu-20.04, diff --git a/.gitignore b/.gitignore index 53b9b881..218ee7a0 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ venv node_modules/ yarn.lock docs/_build/ +venv* diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b20b62c0..8f224355 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,10 @@ Changelog Unreleased ========== - +* Python 3.8, 3.9 support added +* Django 3.0, 3.1 and 3.2 support added +* Python 3.5 and 3.6 support removed +* Django 1.11 support removed 1.0.28 (2021-10-18) =================== diff --git a/djangocms_moderation/admin.py b/djangocms_moderation/admin.py index 2caa756e..6e66ca7e 100644 --- a/djangocms_moderation/admin.py +++ b/djangocms_moderation/admin.py @@ -1,8 +1,5 @@ -from __future__ import unicode_literals - from django import forms from django.apps import apps -from django.conf.urls import url from django.contrib import admin, messages from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType @@ -11,9 +8,9 @@ from django.http import Http404, HttpResponseRedirect from django.shortcuts import get_object_or_404, render from django.template.loader import render_to_string -from django.urls import reverse +from django.urls import re_path, reverse from django.utils.html import format_html, format_html_join -from django.utils.translation import ugettext, ugettext_lazy as _, ungettext +from django.utils.translation import gettext, gettext_lazy as _, ngettext from cms.admin.placeholderadmin import PlaceholderAdminMixin from cms.toolbar.utils import get_object_preview_url @@ -78,7 +75,7 @@ def has_delete_permission(self, request, obj=None): def show_user(self, obj): _name = obj.get_by_user_name() - return ugettext("By {user}").format(user=_name) + return gettext("By {user}").format(user=_name) show_user.short_description = _("Status") @@ -152,7 +149,7 @@ def get_urls(self): info = self.model._meta.app_label, self.model._meta.model_name return [ - url( + re_path( r'^delete_selected/', self.admin_site.admin_view(self.delete_selected_view), name='{}_{}_delete'.format(*info), @@ -270,13 +267,13 @@ def get_status(self, obj): if last_action: if obj.moderation_request.version_can_be_published(): - status = ugettext('Ready for publishing') + status = gettext('Ready for publishing') elif obj.moderation_request.is_rejected(): - status = ugettext('Pending author rework') + status = gettext('Pending author rework') elif obj.moderation_request.is_active and obj.moderation_request.has_pending_step(): next_step = obj.moderation_request.get_next_required() role = next_step.role.name - status = ugettext('Pending %(role)s approval') % {'role': role} + status = gettext('Pending %(role)s approval') % {'role': role} elif not obj.moderation_request.version.can_be_published(): status = obj.moderation_request.version.get_state_display() else: @@ -285,9 +282,9 @@ def get_status(self, obj): 'action': last_action.get_action_display(), 'name': user_name, } - status = ugettext('%(action)s by %(name)s') % message_data + status = gettext('%(action)s by %(name)s') % message_data else: - status = ugettext('Ready for submission') + status = gettext('Ready for submission') return status def get_comments_link(self, obj): @@ -450,7 +447,7 @@ def _traverse_moderation_nodes(node_item): queryset.delete() messages.success( request, - ungettext( + ngettext( '%(count)d request successfully deleted', '%(count)d requests successfully deleted', num_deleted_requests @@ -504,22 +501,22 @@ def get_urls(self): info = self.model._meta.app_label, self.model._meta.model_name return [ - url( + re_path( r"^approve/", self.admin_site.admin_view(self.approved_view), name="{}_{}_approve".format(*info), ), - url( + re_path( r"^rework/", self.admin_site.admin_view(self.rework_view), name="{}_{}_rework".format(*info), ), - url( + re_path( r"^publish/", self.admin_site.admin_view(self.published_view), name="{}_{}_publish".format(*info), ), - url( + re_path( r"^resubmit/", self.admin_site.admin_view(self.resubmit_view), name="{}_{}_resubmit".format(*info), @@ -592,7 +589,7 @@ def resubmit_view(self, request): messages.success( request, - ungettext( + ngettext( "%(count)d request successfully resubmitted for review", "%(count)d requests successfully resubmitted for review", len(resubmitted_requests), @@ -639,7 +636,7 @@ def published_view(self, request): messages.success( request, - ungettext( + ngettext( "%(count)d request successfully published", "%(count)d requests successfully published", len(published_moderation_requests), @@ -698,7 +695,7 @@ def rework_view(self, request): messages.success( request, - ungettext( + ngettext( "%(count)d request successfully submitted for rework", "%(count)d requests successfully submitted for rework", len(rejected_requests), @@ -790,7 +787,7 @@ def approved_view(self, request): messages.success( request, - ungettext( + ngettext( "%(count)d request successfully approved", "%(count)d requests successfully approved", len(approved_requests), @@ -1088,7 +1085,7 @@ def get_comments_link(self, obj): def get_urls(self): def _url(regex, fn, name, **kwargs): - return url(regex, self.admin_site.admin_view(fn), kwargs=kwargs, name=name) + return re_path(regex, self.admin_site.admin_view(fn), kwargs=kwargs, name=name) url_patterns = [ _url( @@ -1138,7 +1135,7 @@ class ConfirmationPageAdmin(PlaceholderAdminMixin, admin.ModelAdmin): def get_urls(self): def _url(regex, fn, name, **kwargs): - return url(regex, self.admin_site.admin_view(fn), kwargs=kwargs, name=name) + return re_path(regex, self.admin_site.admin_view(fn), kwargs=kwargs, name=name) url_patterns = [ _url( @@ -1191,7 +1188,7 @@ def form_data(self, obj): "", "

{}: {}
{}: {}

", ( - (ugettext("Question"), d["label"], ugettext("Answer"), d["value"]) + (gettext("Question"), d["label"], gettext("Answer"), d["value"]) for d in data ), ) diff --git a/djangocms_moderation/admin_actions.py b/djangocms_moderation/admin_actions.py index c5ae2aef..07fc3eea 100644 --- a/djangocms_moderation/admin_actions.py +++ b/djangocms_moderation/admin_actions.py @@ -1,13 +1,13 @@ from collections import defaultdict from functools import partial -from django.contrib import admin +from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied from django.db.models import Q from django.http import HttpResponseRedirect from django.shortcuts import reverse -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from cms.utils.urlutils import add_url_parameters @@ -24,7 +24,7 @@ def resubmit_selected(modeladmin, request, queryset): Validate and re-submit all the selected moderation requests for moderation and notify reviewers via email. """ - selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME) + selected = request.POST.getlist(ACTION_CHECKBOX_NAME) url = "{}?ids={}&collection_id={}".format( reverse("admin:djangocms_moderation_moderationrequest_resubmit"), ",".join(selected), @@ -41,7 +41,7 @@ def reject_selected(modeladmin, request, queryset): Validate and reject all the selected moderation requests and notify the author about these requests """ - selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME) + selected = request.POST.getlist(ACTION_CHECKBOX_NAME) url = "{}?ids={}&collection_id={}".format( reverse("admin:djangocms_moderation_moderationrequest_rework"), ",".join(selected), @@ -54,7 +54,7 @@ def reject_selected(modeladmin, request, queryset): def approve_selected(modeladmin, request, queryset): - selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME) + selected = request.POST.getlist(ACTION_CHECKBOX_NAME) url = "{}?ids={}&collection_id={}".format( reverse("admin:djangocms_moderation_moderationrequest_approve"), ",".join(selected), @@ -70,7 +70,7 @@ def delete_selected(modeladmin, request, queryset): if not modeladmin.has_delete_permission(request): raise PermissionDenied - selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME) + selected = request.POST.getlist(ACTION_CHECKBOX_NAME) url = "{}?ids={}&collection_id={}".format( reverse('admin:djangocms_moderation_moderationrequesttreenode_delete'), ",".join(selected), @@ -87,7 +87,7 @@ def publish_selected(modeladmin, request, queryset): if request.user != request._collection.author: raise PermissionDenied - selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME) + selected = request.POST.getlist(ACTION_CHECKBOX_NAME) url = "{}?ids={}&collection_id={}".format( reverse("admin:djangocms_moderation_moderationrequest_publish"), ",".join(selected), diff --git a/djangocms_moderation/apps.py b/djangocms_moderation/apps.py index a7dda494..cbeed482 100644 --- a/djangocms_moderation/apps.py +++ b/djangocms_moderation/apps.py @@ -1,7 +1,5 @@ -from __future__ import unicode_literals - from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class ModerationConfig(AppConfig): diff --git a/djangocms_moderation/cms_toolbars.py b/djangocms_moderation/cms_toolbars.py index f80470cb..6181cfb7 100644 --- a/djangocms_moderation/cms_toolbars.py +++ b/djangocms_moderation/cms_toolbars.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- from django.contrib.auth import get_permission_codename -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from cms.cms_toolbars import ADMIN_MENU_IDENTIFIER from cms.utils.urlutils import add_url_parameters diff --git a/djangocms_moderation/conf.py b/djangocms_moderation/conf.py index 417d5500..e7008be7 100644 --- a/djangocms_moderation/conf.py +++ b/djangocms_moderation/conf.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ UUID_BACKEND = "djangocms_moderation.backends.uuid4_backend" diff --git a/djangocms_moderation/constants.py b/djangocms_moderation/constants.py index d3e3a1f5..8b64c003 100644 --- a/djangocms_moderation/constants.py +++ b/djangocms_moderation/constants.py @@ -1,6 +1,4 @@ -from __future__ import unicode_literals - -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ # NOTE: those are not just numbers!! we will do binary AND on them, diff --git a/djangocms_moderation/contrib/moderation_forms/cms_plugins.py b/djangocms_moderation/contrib/moderation_forms/cms_plugins.py index 64b29794..61e23625 100644 --- a/djangocms_moderation/contrib/moderation_forms/cms_plugins.py +++ b/djangocms_moderation/contrib/moderation_forms/cms_plugins.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from cms.plugin_pool import plugin_pool diff --git a/djangocms_moderation/contrib/moderation_forms/migrations/0001_initial.py b/djangocms_moderation/contrib/moderation_forms/migrations/0001_initial.py index cbb95f32..c2ab629c 100644 --- a/djangocms_moderation/contrib/moderation_forms/migrations/0001_initial.py +++ b/djangocms_moderation/contrib/moderation_forms/migrations/0001_initial.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.12 on 2018-05-03 09:15 -from __future__ import unicode_literals - from django.db import migrations diff --git a/djangocms_moderation/contrib/moderation_forms/models.py b/djangocms_moderation/contrib/moderation_forms/models.py index f5ab7f44..72027ccd 100644 --- a/djangocms_moderation/contrib/moderation_forms/models.py +++ b/djangocms_moderation/contrib/moderation_forms/models.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from aldryn_forms.models import FormPlugin diff --git a/djangocms_moderation/emails.py b/djangocms_moderation/emails.py index 35acc07c..319a53e6 100644 --- a/djangocms_moderation/emails.py +++ b/djangocms_moderation/emails.py @@ -1,11 +1,9 @@ -from __future__ import unicode_literals - from django.conf import settings from django.core.mail import EmailMessage from django.template.loader import render_to_string from django.urls import reverse -from django.utils.encoding import force_text -from django.utils.translation import ugettext_lazy as _ +from django.utils.encoding import force_str +from django.utils.translation import gettext_lazy as _ from .conf import EMAIL_NOTIFICATIONS_FAIL_SILENTLY from .utils import get_absolute_url @@ -40,7 +38,7 @@ def _send_email( template = "djangocms_moderation/emails/moderation-request/{}".format(template) # TODO What language should the email be sent in? e.g. `with force_language(lang):` - subject = force_text(subject) + subject = force_str(subject) content = render_to_string(template, context) message = EmailMessage( diff --git a/djangocms_moderation/filters.py b/djangocms_moderation/filters.py index 8cd6bd59..a00ae402 100644 --- a/djangocms_moderation/filters.py +++ b/djangocms_moderation/filters.py @@ -1,8 +1,8 @@ from django.contrib import admin from django.contrib.auth import get_user_model from django.db.models import Q -from django.utils.encoding import force_text -from django.utils.translation import ugettext_lazy as _ +from django.utils.encoding import force_str +from django.utils.translation import gettext_lazy as _ from . import constants, helpers @@ -22,7 +22,7 @@ def lookups(self, request, model_admin): options = [] for user in helpers.get_all_moderators(): options.append( - (force_text(user.pk), user.get_full_name() or user.get_username()) + (force_str(user.pk), user.get_full_name() or user.get_username()) ) return options @@ -44,7 +44,7 @@ def lookups(self, request, model_admin): # collect all unique users from the three queries for user in helpers.get_all_reviewers(): options.append( - (force_text(user.pk), user.get_full_name() or user.get_username()) + (force_str(user.pk), user.get_full_name() or user.get_username()) ) return options @@ -78,7 +78,7 @@ def choices(self, changelist): } for lookup, title in self.lookup_choices: yield { - "selected": self.value() == force_text(lookup), + "selected": self.value() == force_str(lookup), "query_string": changelist.get_query_string( {self.parameter_name: lookup}, [] ), diff --git a/djangocms_moderation/forms.py b/djangocms_moderation/forms.py index 3d5d54b9..7ff8bd8d 100644 --- a/djangocms_moderation/forms.py +++ b/djangocms_moderation/forms.py @@ -1,11 +1,9 @@ -from __future__ import unicode_literals - from django import forms from django.contrib import admin from django.contrib.admin.widgets import RelatedFieldWidgetWrapper from django.contrib.auth import get_user_model from django.forms.forms import NON_FIELD_ERRORS -from django.utils.translation import ugettext, ugettext_lazy as _, ungettext +from django.utils.translation import gettext, gettext_lazy as _, ngettext from adminsortable2.admin import CustomInlineFormSet from djangocms_versioning.models import Version @@ -99,7 +97,7 @@ def configure_moderator_field(self): if next_step: next_role = next_step.role users = next_step.role.get_users_queryset() - self.fields["moderator"].empty_label = ugettext("Any {role}").format( + self.fields["moderator"].empty_label = gettext("Any {role}").format( role=next_role.name ) self.fields["moderator"].queryset = users.exclude(pk=self.user.pk) @@ -170,7 +168,7 @@ def clean_versions(self): if not eligible_versions: raise forms.ValidationError( - ungettext( + ngettext( "Your item is either locked, not enabled for moderation," "or is part of another active moderation request", "Your items are either locked, not enabled for moderation," @@ -197,7 +195,7 @@ def __init__(self, *args, **kwargs): def configure_moderator_field(self): next_role = self.collection.workflow.first_step.role users = next_role.get_users_queryset().exclude(pk=self.user.pk) - self.fields["moderator"].empty_label = ugettext("Any {role}").format( + self.fields["moderator"].empty_label = gettext("Any {role}").format( role=next_role.name ) self.fields["moderator"].queryset = users diff --git a/djangocms_moderation/handlers.py b/djangocms_moderation/handlers.py index 943a94f7..768ba335 100644 --- a/djangocms_moderation/handlers.py +++ b/djangocms_moderation/handlers.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import json from django.dispatch import receiver diff --git a/djangocms_moderation/helpers.py b/djangocms_moderation/helpers.py index 201b2380..c3f38e62 100644 --- a/djangocms_moderation/helpers.py +++ b/djangocms_moderation/helpers.py @@ -4,7 +4,7 @@ from django.db.models import Q from django.template.defaultfilters import truncatechars from django.urls import reverse -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from cms.utils.plugins import downcast_plugins diff --git a/djangocms_moderation/managers.py b/djangocms_moderation/managers.py index 2d8f7e6a..688a0012 100644 --- a/djangocms_moderation/managers.py +++ b/djangocms_moderation/managers.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.db import models from django.db.models import Manager, Q diff --git a/djangocms_moderation/migrations/0001_initial.py b/djangocms_moderation/migrations/0001_initial.py index f8d2aa42..b1464ba4 100644 --- a/djangocms_moderation/migrations/0001_initial.py +++ b/djangocms_moderation/migrations/0001_initial.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-08-16 08:57 -from __future__ import unicode_literals - import cms.models.fields from django.conf import settings from django.db import migrations, models diff --git a/djangocms_moderation/migrations/0002_auto_20180905_1152.py b/djangocms_moderation/migrations/0002_auto_20180905_1152.py index 41a7548d..f80795dc 100644 --- a/djangocms_moderation/migrations/0002_auto_20180905_1152.py +++ b/djangocms_moderation/migrations/0002_auto_20180905_1152.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-09-05 10:52 -from __future__ import unicode_literals - from django.conf import settings from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0003_auto_20180903_1206.py b/djangocms_moderation/migrations/0003_auto_20180903_1206.py index 25bd0dcd..8bbc691c 100644 --- a/djangocms_moderation/migrations/0003_auto_20180903_1206.py +++ b/djangocms_moderation/migrations/0003_auto_20180903_1206.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-09-03 11:06 -from __future__ import unicode_literals - from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0004_auto_20180907_1206.py b/djangocms_moderation/migrations/0004_auto_20180907_1206.py index d40417ec..9afdd8f7 100644 --- a/djangocms_moderation/migrations/0004_auto_20180907_1206.py +++ b/djangocms_moderation/migrations/0004_auto_20180907_1206.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-09-07 11:06 -from __future__ import unicode_literals - from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0005_auto_20180919_1348.py b/djangocms_moderation/migrations/0005_auto_20180919_1348.py index d0b57990..ffc1e8be 100644 --- a/djangocms_moderation/migrations/0005_auto_20180919_1348.py +++ b/djangocms_moderation/migrations/0005_auto_20180919_1348.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-09-19 12:48 -from __future__ import unicode_literals - from django.conf import settings from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0006_auto_20181001_1840.py b/djangocms_moderation/migrations/0006_auto_20181001_1840.py index e3f16933..409bb06d 100644 --- a/djangocms_moderation/migrations/0006_auto_20181001_1840.py +++ b/djangocms_moderation/migrations/0006_auto_20181001_1840.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-10-01 17:40 -from __future__ import unicode_literals - from django.conf import settings from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0007_auto_20181002_1725.py b/djangocms_moderation/migrations/0007_auto_20181002_1725.py index f30c7da4..651be569 100644 --- a/djangocms_moderation/migrations/0007_auto_20181002_1725.py +++ b/djangocms_moderation/migrations/0007_auto_20181002_1725.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.16 on 2018-10-02 16:25 -from __future__ import unicode_literals - from django.db import migrations diff --git a/djangocms_moderation/migrations/0008_auto_20181002_1833.py b/djangocms_moderation/migrations/0008_auto_20181002_1833.py index d0b5ff82..497796b6 100644 --- a/djangocms_moderation/migrations/0008_auto_20181002_1833.py +++ b/djangocms_moderation/migrations/0008_auto_20181002_1833.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2018-10-02 16:33 -from __future__ import unicode_literals - from django.conf import settings from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0009_auto_20181005_1534.py b/djangocms_moderation/migrations/0009_auto_20181005_1534.py index 3302a6c0..34803320 100644 --- a/djangocms_moderation/migrations/0009_auto_20181005_1534.py +++ b/djangocms_moderation/migrations/0009_auto_20181005_1534.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-10-05 14:34 -from __future__ import unicode_literals - from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0010_auto_20181008_1317.py b/djangocms_moderation/migrations/0010_auto_20181008_1317.py index 64d26983..a6f69b54 100644 --- a/djangocms_moderation/migrations/0010_auto_20181008_1317.py +++ b/djangocms_moderation/migrations/0010_auto_20181008_1317.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-10-08 12:17 -from __future__ import unicode_literals - from django.db import migrations diff --git a/djangocms_moderation/migrations/0011_auto_20181008_1328.py b/djangocms_moderation/migrations/0011_auto_20181008_1328.py index 27a1cdbb..23829d74 100644 --- a/djangocms_moderation/migrations/0011_auto_20181008_1328.py +++ b/djangocms_moderation/migrations/0011_auto_20181008_1328.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-10-08 12:28 -from __future__ import unicode_literals - from django.conf import settings from django.db import migrations from django.db import migrations, models diff --git a/djangocms_moderation/migrations/0012_auto_20181016_1319.py b/djangocms_moderation/migrations/0012_auto_20181016_1319.py index 8a861a50..6c9865bb 100644 --- a/djangocms_moderation/migrations/0012_auto_20181016_1319.py +++ b/djangocms_moderation/migrations/0012_auto_20181016_1319.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.13 on 2018-10-16 12:19 -from __future__ import unicode_literals - from django.conf import settings from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0013_auto_20181122_1110.py b/djangocms_moderation/migrations/0013_auto_20181122_1110.py index fd2236be..78838ad0 100644 --- a/djangocms_moderation/migrations/0013_auto_20181122_1110.py +++ b/djangocms_moderation/migrations/0013_auto_20181122_1110.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2018-11-22 11:10 -from __future__ import unicode_literals - from django.conf import settings from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0014_auto_20190313_1638.py b/djangocms_moderation/migrations/0014_auto_20190313_1638.py index 7f702e2e..cd4f8b0d 100644 --- a/djangocms_moderation/migrations/0014_auto_20190313_1638.py +++ b/djangocms_moderation/migrations/0014_auto_20190313_1638.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2019-03-13 16:38 -from __future__ import unicode_literals - from django.db import migrations, models diff --git a/djangocms_moderation/migrations/0014_auto_20190315_1723.py b/djangocms_moderation/migrations/0014_auto_20190315_1723.py index 23795a83..d420dc9c 100644 --- a/djangocms_moderation/migrations/0014_auto_20190315_1723.py +++ b/djangocms_moderation/migrations/0014_auto_20190315_1723.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2019-03-15 17:23 -from __future__ import unicode_literals - from django.db import migrations diff --git a/djangocms_moderation/migrations/0016_moderationrequesttreenode.py b/djangocms_moderation/migrations/0016_moderationrequesttreenode.py index 209b7a1b..592c7f89 100644 --- a/djangocms_moderation/migrations/0016_moderationrequesttreenode.py +++ b/djangocms_moderation/migrations/0016_moderationrequesttreenode.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2019-03-11 16:45 -from __future__ import unicode_literals - from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/models.py b/djangocms_moderation/models.py index edb844df..25c2afd6 100644 --- a/djangocms_moderation/models.py +++ b/djangocms_moderation/models.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import json from django.conf import settings @@ -8,9 +6,8 @@ from django.core.exceptions import ValidationError from django.db import models, transaction from django.urls import reverse -from django.utils.encoding import python_2_unicode_compatible from django.utils.functional import cached_property -from django.utils.translation import ugettext, ugettext_lazy as _ +from django.utils.translation import gettext, gettext_lazy as _ from cms.models.fields import PlaceholderField @@ -25,7 +22,6 @@ from . import conf, constants, signals # isort:skip -@python_2_unicode_compatible class ConfirmationPage(models.Model): CONTENT_TYPES = ( (constants.CONTENT_TYPE_PLAIN, _("Plain")), @@ -71,7 +67,6 @@ def is_valid(self, active_request, for_step, is_reviewed=False): return True -@python_2_unicode_compatible class Role(models.Model): name = models.CharField( verbose_name=_('name'), @@ -102,7 +97,7 @@ def __str__(self): def clean(self): if self.user_id and self.group_id: - message = ugettext("Can't pick both user and group. Only one.") + message = gettext("Can't pick both user and group. Only one.") raise ValidationError(message) def user_is_assigned(self, user): @@ -116,7 +111,6 @@ def get_users_queryset(self): return self.group.user_set.all() -@python_2_unicode_compatible class Workflow(models.Model): name = models.CharField(verbose_name=_("name"), max_length=120, unique=True) is_default = models.BooleanField(verbose_name=_("is default"), default=False) @@ -164,7 +158,7 @@ def clean(self): workflows = workflows.exclude(pk=self.pk) if workflows.exists(): - message = ugettext("Can't have two default workflows, only one is allowed.") + message = gettext("Can't have two default workflows, only one is allowed.") raise ValidationError(message) @cached_property @@ -172,7 +166,6 @@ def first_step(self): return self.steps.first() -@python_2_unicode_compatible class WorkflowStep(models.Model): role = models.ForeignKey( to=Role, verbose_name=_("role"), on_delete=models.CASCADE @@ -413,7 +406,6 @@ def __str__(self): return str(self.id) -@python_2_unicode_compatible class ModerationRequest(models.Model): collection = models.ForeignKey( to=ModerationCollection, @@ -601,7 +593,6 @@ def set_compliance_number(self): self.save(update_fields=["compliance_number"]) -@python_2_unicode_compatible class ModerationRequestAction(models.Model): action = models.CharField( verbose_name=_("status"), max_length=30, choices=constants.ACTION_CHOICES diff --git a/djangocms_moderation/monkeypatch.py b/djangocms_moderation/monkeypatch.py index 00d0694f..a439850e 100644 --- a/djangocms_moderation/monkeypatch.py +++ b/djangocms_moderation/monkeypatch.py @@ -1,5 +1,5 @@ from django.utils.html import format_html -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from cms.models import fields from cms.utils.urlutils import add_url_parameters diff --git a/djangocms_moderation/signals.py b/djangocms_moderation/signals.py index 46c28975..dc6a53b1 100644 --- a/djangocms_moderation/signals.py +++ b/djangocms_moderation/signals.py @@ -1,19 +1,8 @@ import django.dispatch -confirmation_form_submission = django.dispatch.Signal( - providing_args=["page", "language", "user", "form_data"] -) +confirmation_form_submission = django.dispatch.Signal() -submitted_for_review = django.dispatch.Signal( - providing_args=["collection", "moderation_requests", "user", "rework"] -) +submitted_for_review = django.dispatch.Signal() -published = django.dispatch.Signal( - providing_args=[ - "collection", - "moderator", - "moderation_requests", - "workflow" - ] -) +published = django.dispatch.Signal() diff --git a/djangocms_moderation/utils.py b/djangocms_moderation/utils.py index 10c4d52b..1f29c242 100644 --- a/djangocms_moderation/utils.py +++ b/djangocms_moderation/utils.py @@ -1,10 +1,9 @@ -from __future__ import unicode_literals +from functools import lru_cache +from urllib.parse import parse_qs, urljoin from django.conf import settings from django.contrib.sites.models import Site -from django.utils.lru_cache import lru_cache from django.utils.module_loading import import_string -from django.utils.six.moves.urllib.parse import parse_qs, urljoin from django.utils.translation import override as force_language from cms.utils.urlutils import admin_reverse diff --git a/djangocms_moderation/views.py b/djangocms_moderation/views.py index cee30199..95d4e839 100644 --- a/djangocms_moderation/views.py +++ b/djangocms_moderation/views.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.contrib import admin, messages from django.db import transaction from django.http import Http404, HttpResponseRedirect @@ -7,7 +5,7 @@ from django.urls import reverse from django.utils.decorators import method_decorator from django.utils.http import is_safe_url, urlquote -from django.utils.translation import ugettext_lazy as _, ungettext +from django.utils.translation import gettext_lazy as _, ngettext from django.views.generic import FormView from cms.models import PageContent @@ -66,7 +64,7 @@ def form_valid(self, form): messages.success( self.request, - ungettext( + ngettext( "%(count)d item successfully added to moderation collection", "%(count)d items successfully added to moderation collection", total_added, diff --git a/setup.py b/setup.py index 331b4081..0835848d 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ INSTALL_REQUIREMENTS = [ - "Django>=1.11,<3.0", + "Django>=2.2,<4.0", "django-cms", "django-sekizai>=0.7", "django-admin-sortable2>=0.6.4", diff --git a/tests/requirements/dj11_cms40.txt b/tests/requirements/dj11_cms40.txt deleted file mode 100644 index 6019903a..00000000 --- a/tests/requirements/dj11_cms40.txt +++ /dev/null @@ -1,9 +0,0 @@ --r requirements_base.txt - -Django>=1.11,<2.0 -django-admin-sortable2<1.0.0 -django-filer<2.0.0 -django-classy-tags<2.0.0 -django-sekizai<2.0.0 -# Please note that aldryn-forms version 5 can only be used with django >2 and deprecates <2 completely. -aldryn-forms<6.0.0 diff --git a/tests/requirements/dj22_cms40.txt b/tests/requirements/dj22_cms40.txt index 4ff11633..4e51203c 100644 --- a/tests/requirements/dj22_cms40.txt +++ b/tests/requirements/dj22_cms40.txt @@ -1,7 +1,6 @@ --r requirements_base.txt +-r ./requirements_base.txt Django>=2.2,<3.0 -django-filer -django-classy-tags -django-sekizai -aldryn-forms + +django-admin-sortable2<1.0 +django_polymorphic==2.0.3 diff --git a/tests/requirements/dj32_cms40.txt b/tests/requirements/dj32_cms40.txt new file mode 100644 index 00000000..d19b191e --- /dev/null +++ b/tests/requirements/dj32_cms40.txt @@ -0,0 +1,6 @@ +-r ./requirements_base.txt + +Django>=3.2,<4.0 + +django-admin-sortable2 +django_polymorphic diff --git a/tests/requirements/requirements_base.txt b/tests/requirements/requirements_base.txt index a3789121..b7cd9390 100644 --- a/tests/requirements/requirements_base.txt +++ b/tests/requirements/requirements_base.txt @@ -1,8 +1,11 @@ +aldryn-forms cachetools coverage -django_polymorphic==2.0.3 +django-classy-tags +django-filer +django-sekizai django-simple-captcha -djangocms_helper +django-app-helper factory-boy flake8 isort @@ -11,7 +14,7 @@ pyflakes>=2.1.1 python-dateutil>=2.4 # Unreleased django-cms 4.0 compatible packages -https://github.com/django-cms/django-cms/tarball/release/4.0.x#egg=django-cms +https://github.com/django-cms/django-cms/tarball/develop-4#egg=django-cms https://github.com/django-cms/djangocms-text-ckeditor/tarball/support/4.0.x#egg=djangocms-text-ckeditor https://github.com/django-cms/djangocms-versioning/tarball/master#egg=djangocms-versioning https://github.com/FidelityInternational/djangocms-version-locking/tarball/master#egg=djangocms-version-locking diff --git a/tests/settings.py b/tests/settings.py index 311abff4..67561ba3 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -1,4 +1,5 @@ HELPER_SETTINGS = { + "SECRET_KEY": "moderationtestsuitekey", "INSTALLED_APPS": [ "tests.utils.app_1", "tests.utils.app_2", @@ -27,6 +28,7 @@ "djangocms_moderation": None, "aldryn_forms": None, }, + "DEFAULT_AUTO_FIELD": "django.db.models.AutoField", } diff --git a/tests/test_admin_actions.py b/tests/test_admin_actions.py index 0114882c..b0c3fbd8 100644 --- a/tests/test_admin_actions.py +++ b/tests/test_admin_actions.py @@ -1,7 +1,7 @@ import mock import unittest -from django.contrib.admin import ACTION_CHECKBOX_NAME +from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME from django.contrib.auth.models import Group from django.test import TransactionTestCase from django.urls import reverse @@ -639,13 +639,13 @@ def test_signal_when_published(self): self.client.post(response.url) args, kwargs = signal.calls[0] published_mr = kwargs['moderation_requests'] - self.assertEquals(signal.call_count, 1) - self.assertEquals(kwargs['sender'], ModerationRequest) - self.assertEquals(kwargs['collection'], self.collection) - self.assertEquals(kwargs['moderator'], self.collection.author) - self.assertEquals(len(published_mr), 1) - self.assertEquals(published_mr[0], self.moderation_request1) - self.assertEquals(kwargs['workflow'], self.collection.workflow) + self.assertEqual(signal.call_count, 1) + self.assertEqual(kwargs['sender'], ModerationRequest) + self.assertEqual(kwargs['collection'], self.collection) + self.assertEqual(kwargs['moderator'], self.collection.author) + self.assertEqual(len(published_mr), 1) + self.assertEqual(published_mr[0], self.moderation_request1) + self.assertEqual(kwargs['workflow'], self.collection.workflow) @unittest.skip("Skip until collection status bugs fixed") @mock.patch("django.contrib.messages.success") diff --git a/tests/test_cms_toolbars.py b/tests/test_cms_toolbars.py index 7b62650e..62727ebe 100644 --- a/tests/test_cms_toolbars.py +++ b/tests/test_cms_toolbars.py @@ -28,7 +28,7 @@ def _get_page_request(self, page, user): request.session = {} request.user = user request.current_page = page - mid = ToolbarMiddleware() + mid = ToolbarMiddleware(request) mid.process_request(request) if hasattr(request, "toolbar"): request.toolbar.populate() diff --git a/tests/test_models.py b/tests/test_models.py index 3b592261..b00b6bfa 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -622,7 +622,7 @@ def test_submit_for_review(self, mock_ncm): self.collection1.refresh_from_db() # Collection should lock itself - self.assertEquals(self.collection1.status, constants.IN_REVIEW) + self.assertEqual(self.collection1.status, constants.IN_REVIEW) # We will now have 2 actions with status STARTED. self.assertEqual( 2, @@ -652,7 +652,7 @@ def test_cancel(self): self.collection1.cancel(self.user) self.collection1.refresh_from_db() - self.assertEquals(self.collection1.status, constants.CANCELLED) + self.assertEqual(self.collection1.status, constants.CANCELLED) # Only 1 active request will be cancelled actions = ModerationRequestAction.objects.filter( diff --git a/tests/test_utils.py b/tests/test_utils.py index 9ac31098..db496568 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -23,7 +23,7 @@ def test_extract_filter_param_from_changelist_url(self): collection_id = utils.extract_filter_param_from_changelist_url( mock_request, "_changelist_filters", "collection__id__exact" ) - self.assertEquals(collection_id, "1") + self.assertEqual(collection_id, "1") mock_request = self.rf.get( "/admin/djangocms_moderation/collectioncomment/add/?_changelist_filters=collection__id__exact%3D4" @@ -31,7 +31,7 @@ def test_extract_filter_param_from_changelist_url(self): collection_id = utils.extract_filter_param_from_changelist_url( mock_request, "_changelist_filters", "collection__id__exact" ) - self.assertEquals(collection_id, "4") + self.assertEqual(collection_id, "4") mock_request = self.rf.get( "/admin/djangocms_moderation/requestcomment/add/?_changelist_filters=moderation_request__id__exact%3D1" @@ -39,7 +39,7 @@ def test_extract_filter_param_from_changelist_url(self): action_id = utils.extract_filter_param_from_changelist_url( mock_request, "_changelist_filters", "moderation_request__id__exact" ) - self.assertEquals(action_id, "1") + self.assertEqual(action_id, "1") mock_request = self.rf.get( "/admin/djangocms_moderation/requestcomment/add/?_changelist_filters=moderation_request__id__exact%3D2" @@ -47,7 +47,7 @@ def test_extract_filter_param_from_changelist_url(self): action_id = utils.extract_filter_param_from_changelist_url( mock_request, "_changelist_filters", "moderation_request__id__exact" ) - self.assertEquals(action_id, "2") + self.assertEqual(action_id, "2") def test_get_active_moderation_request(self): self.assertEqual( diff --git a/tox.ini b/tox.ini index 7483eb32..24c8a857 100644 --- a/tox.ini +++ b/tox.ini @@ -1,28 +1,23 @@ [tox] envlist = - flake8 - isort - py{36,37}-dj{111,20}-sqlite-cms4-aldrynforms4 - py{36,37}-dj{21,22}-sqlite-cms4-aldrynforms5 + dj32-flake8 + dj32-isort + py{37,38,39}-dj{22,32}-sqlite-cms4 skip_missing_interpreters=True [testenv] deps = - -r{toxinidir}/tests/requirements.txt + dj22: -r{toxinidir}/tests/requirements/django_22.txt + dj22: Django>=2.2,<2.3 - dj111: Django>=1.11,<2.0 - dj20: Django>=2.0,<2.1 - dj21: Django>=2.1,<2.2 - dj22: Django>=2.2,<3.0 - - cms4: https://github.com/divio/django-cms/archive/release/4.0.x.zip - aldrynforms5: https://github.com/divio/aldryn-forms/archive/master.zip - aldrynforms4: aldryn-forms==4.0.1 + dj32: -r{toxinidir}/tests/requirements/django_32.txt + dj32: Django>=3.2,<3.3 basepython = - py36: python3.6 py37: python3.7 + py38: python3.8 + py39: python3.9 commands = {envpython} --version @@ -32,8 +27,8 @@ commands = [testenv:flake8] commands = flake8 -basepython = python3.6 +basepython = python3.9 [testenv:isort] commands = isort --recursive --check-only --diff {toxinidir} -basepython = python3.6 +basepython = python3.9