Repository: jonasundderwolf/django-image-cropping (language: python)

Issue:
Django 4 support
Hi,

I've just upgraded to Django 4 and found at least one issue related to deprecated methods:
- in utils.py, there is an import of ugettext wich ihrs been removed and can be replaced by just gettext: 
```from django.utils.translation import gettext as _```

Maybe we can collect issues here. And then provide a PR.


Discussion / hints:
I tried but I can't event run the tests. Is there any contribution / building / testing documentation?
Hey @jwedel,
does this help and work for you? -> https://github.com/jonasundderwolf/django-image-cropping/blob/master/README.rst#testing

Fix patch:
diff --git a/.coveragerc b/.coveragerc
index 33d29f25..ee07ecc1 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,6 +1,8 @@
 [run]
 branch = True
-include = example/*
+include =
+    example/*
+    image_cropping/*
 omit =
     */migrations/*
     */conf/*
diff --git a/example/requirements.txt b/example/requirements.txt
index 8b870fee..b91ae317 100644
--- a/example/requirements.txt
+++ b/example/requirements.txt
@@ -1,14 +1,14 @@
 -e .
-easy_thumbnails==2.7.0
-WebTest==2.0.35
-django-webtest==1.9.7
-coverage==5.3
-isort==5.5.3
-pytest==6.0.2
-pytest-cov==2.10.1
-pytest-django==3.10.0
+easy_thumbnails==2.8.1
+WebTest==3.0.0
+django-webtest==1.9.9
+coverage==5.5
+isort==5.10.1
+pytest==6.2.5
+pytest-cov==3.0.0
+pytest-django==4.5.2
 pytest-env==0.6.2
-pytest-factoryboy==2.0.3
-pytest-html==2.1.1
-pytest-isort==1.2.0
-pytest-black==0.3.11
+pytest-factoryboy==2.1.0
+pytest-html==3.1.1
+pytest-isort==2.0.0
+pytest-black==0.3.12
diff --git a/example/settings.py b/example/settings.py
index bfba4bf1..2f050efa 100644
--- a/example/settings.py
+++ b/example/settings.py
@@ -4,8 +4,6 @@
 
 from easy_thumbnails.conf import settings as thumbnail_settings
 
-import django.template
-
 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
 
 DEBUG = True
@@ -18,6 +16,8 @@
 }
 
 TIME_ZONE = "Europe/Berlin"
+# Keep pre Django 4.0 behaviour after upgrading
+USE_TZ = False
 LANGUAGE_CODE = "en-us"
 
 SITE_ID = 1
diff --git a/example/urls.py b/example/urls.py
index 256532b9..10d6f5dc 100644
--- a/example/urls.py
+++ b/example/urls.py
@@ -1,33 +1,34 @@
 from example import views
 
 from django.conf import settings
-from django.conf.urls import static, url
+from django.conf.urls import static
 from django.contrib import admin
+from django.urls import re_path
 
 urlpatterns = [
-    url(r"^$", views.thumbnail_options, name="thumbnail_options"),
-    url(
+    re_path(r"^$", views.thumbnail_options, name="thumbnail_options"),
+    re_path(
         r"^show_foreignkey_thumbnail/$",
         views.thumbnail_foreign_key,
         name="thumbnail_foreign_key",
     ),
-    url(
+    re_path(
         r"^show_foreignkey_thumbnail/(?P<instance_id>\d+)/$",
         views.thumbnail_foreign_key,
         name="thumbnail_foreign_key",
     ),
-    url(
+    re_path(
         r"^modelform_example/(?P<image_id>\d+)/$",
         views.modelform_example,
         name="modelform_example",
     ),
-    url(r"^modelform_example/$", views.modelform_example, name="modelform_example"),
-    url(
+    re_path(r"^modelform_example/$", views.modelform_example, name="modelform_example"),
+    re_path(
         r"^show_thumbnail/(?P<image_id>\d+)/$",
         views.show_thumbnail,
         name="show_thumbnail",
     ),
-    url(r"^admin/", admin.site.urls),
+    re_path(r"^admin/", admin.site.urls),
 ]
 
 urlpatterns += static.static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
diff --git a/image_cropping/backends/base.py b/image_cropping/backends/base.py
index ec4eb73e..a7a74bcd 100644
--- a/image_cropping/backends/base.py
+++ b/image_cropping/backends/base.py
@@ -1,6 +1,6 @@
 import abc
 
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 
 from .. import widgets
 
diff --git a/image_cropping/utils.py b/image_cropping/utils.py
index 8a061e5f..7d91d339 100644
--- a/image_cropping/utils.py
+++ b/image_cropping/utils.py
@@ -1,6 +1,6 @@
 from django.core.exceptions import ImproperlyConfigured
 from django.utils.module_loading import import_string
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 
 from .config import settings
 
diff --git a/tox.ini b/tox.ini
index 0d7057eb..5928a462 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,6 +9,7 @@ envlist =
     py{36,37,38,39}-django30
     py{36,37,38,39}-django31
     py{36,37,38,39}-django32
+    py{38,39}-django40
 
 [gh-actions]
 python =
@@ -19,16 +20,15 @@ python =
 
 [testenv]
 commands =
-    pytest example --create-db --cache-clear --cov-append
-;   # TODO: fixme it is empty and thus failing
-;    coverage report
+    coverage run -m pytest example --create-db --cache-clear --cov-append
+    coverage report
 setenv =
     DJANGO_SETTINGS_MODULE=example.settings
     PYTHONPATH={toxinidir}
 deps =
-    pillow==6.2.2
     -r{toxinidir}/example/requirements.txt
     django22: Django>=2.2,<3.0
     django30: Django>=3.0,<3.1
     django31: Django>=3.1,<3.2
     django32: Django>=3.2,<4
+    django40: Django>=4.0,<4.1


Test patch:
diff --git a/pytest.ini b/pytest.ini
index 9beb666a..de2dadca 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,4 +1,4 @@
 [pytest]
 DJANGO_SETTINGS_MODULE=example.settings
 addopts = --durations=10 --isort --black --durations=10 --reuse-db --cov-config .coveragerc --html test_results.html
-testpaths = example/tests
+testpaths = tests