Drop support for Django 2.2

pull/7141/head
Matt Westcott 2021-04-29 10:57:28 +01:00 zatwierdzone przez Matt Westcott
rodzic 9b1156210c
commit 85c97fe87f
16 zmienionych plików z 51 dodań i 112 usunięć

Wyświetl plik

@ -17,9 +17,8 @@ on:
# - test runs with USE_EMAIL_USER_MODEL=yes and DISABLE_TIMEZONE=yes
# Current configuration:
# - django 2.2, python 3.6, mysql
# - django 3.0, python 3.7, sqlite
# - django 3.1, python 3.8, postgres
# - django 3.0, python 3.6, sqlite
# - django 3.1, python 3.7, postgres
# - django 3.2, python 3.8, postgres
# - django 3.2, python 3.9, mysql
# - django 3.2, python 3.9, sqlite
@ -27,9 +26,8 @@ on:
# - django 3.2, python 3.9, postgres, DISABLE_TIMEZONE=yes
# - django stable/3.2.x, python 3.9, postgres (allow failures)
# - django main, python 3.9, postgres (allow failures)
# - elasticsearch 5, django 2.2, python 3.6, sqlite
# - elasticsearch 6, django 3.0, python 3.7, postgres
# - elasticsearch 7, django 3.1, python 3.8, postgres
# - elasticsearch 5, django 3.0, python 3.6, sqlite
# - elasticsearch 6, django 3.1, python 3.7, postgres
# - elasticsearch 7, django 3.2, python 3.8, postgres
# - elasticsearch 7, django 3.2, python 3.9, sqlite, USE_EMAIL_USER_MODEL=yes
@ -39,7 +37,7 @@ jobs:
strategy:
matrix:
include:
- python: 3.7
- python: 3.6
django: "Django>=3.0,<3.1"
- python: 3.9
django: "Django>=3.1,<3.2"
@ -67,7 +65,7 @@ jobs:
strategy:
matrix:
include:
- python: 3.8
- python: 3.7
django: "Django>=3.1,<3.2"
experimental: false
- python: 3.8
@ -123,8 +121,6 @@ jobs:
strategy:
matrix:
include:
- python: 3.6
django: "Django>=2.2,<3.0"
- python: 3.9
django: "Django>=3.2,<3.3"
@ -166,7 +162,7 @@ jobs:
matrix:
include:
- python: 3.6
django: "Django>=2.2,<3.0"
django: "Django>=3.0,<3.1"
steps:
- name: Configure sysctl limits
run: |
@ -250,7 +246,7 @@ jobs:
matrix:
include:
- python: 3.7
django: "Django>=3.0,<3.1"
django: "Django>=3.1,<3.2"
services:
postgres:
@ -297,8 +293,6 @@ jobs:
strategy:
matrix:
include:
- python: 3.8
django: "Django>=3.1,<3.2"
- python: 3.8
django: "Django>=3.2,<3.3"

Wyświetl plik

@ -4,6 +4,7 @@ Changelog
2.14 (xx.xx.xxxx) - IN DEVELOPMENT
~~~~~~~~~~~~~~~~~
* Removed support for Django 2.2
* Added ``ancestor_of`` API filter (Jaap Roes)
* Fix: Invalid filter values for foreign key fields in the API now give an error instead of crashing (Tidjani Dia)
* Fix: Ordering specified in `construct_explorer_page_queryset` hook is now taken into account again by the page explorer API (Andre Fonseca)

Wyświetl plik

@ -56,11 +56,11 @@ _(If you are reading this on GitHub, the details here may not be indicative of t
Wagtail supports:
* Django 2.2.x, 3.0.x, 3.1.x and 3.2.x
* Django 3.0.x, 3.1.x and 3.2.x
* Python 3.6, 3.7, 3.8 and 3.9
* PostgreSQL, MySQL and SQLite as database backends
[Previous versions of Wagtail](https://docs.wagtail.io/en/stable/releases/upgrading.html#compatible-django-python-versions) additionally supported Python 2.7 and Django 1.x.
[Previous versions of Wagtail](https://docs.wagtail.io/en/stable/releases/upgrading.html#compatible-django-python-versions) additionally supported Python 2.7 and Django 1.x - 2.x.
---

Wyświetl plik

@ -5,7 +5,7 @@
Wagtail provides the `wagtail start` command and project template to get you started with a new Wagtail project as quickly as possible, but it's easy to integrate Wagtail into an existing Django project too.
Wagtail is currently compatible with Django 2.2, 3.0, 3.1 and 3.2. First, install the `wagtail` package from PyPI:
Wagtail is currently compatible with Django 3.0, 3.1 and 3.2. First, install the `wagtail` package from PyPI:
```sh
$ pip install wagtail

Wyświetl plik

@ -24,3 +24,8 @@ Bug fixes
Upgrade considerations
======================
Removed support for Django 2.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Django 2.2 is no longer supported as of this release; please upgrade to Django 3.0 or above before upgrading Wagtail.

Wyświetl plik

@ -20,7 +20,7 @@ except ImportError:
install_requires = [
"Django>=2.2,<3.3",
"Django>=3.0,<3.3",
"django-modelcluster>=5.1,<6.0",
"django-taggit>=1.0,<2.0",
"django-treebeard>=4.2.0,<5.0,!=4.5",
@ -109,7 +109,6 @@ https://github.com/wagtail/wagtail/.",
'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 :: 3.2',

Wyświetl plik

@ -2,7 +2,7 @@
skipsdist = True
usedevelop = True
envlist = py{36,37,38,39}-dj{22,30,31,32,32stable,main}-{sqlite,postgres,mysql,mssql}-{elasticsearch7,elasticsearch6,elasticsearch5,noelasticsearch}-{customuser,emailuser}-{tz,notz},
envlist = py{36,37,38,39}-dj{30,31,32,32stable,main}-{sqlite,postgres,mysql,mssql}-{elasticsearch7,elasticsearch6,elasticsearch5,noelasticsearch}-{customuser,emailuser}-{tz,notz},
[testenv]
install_command = pip install -e ".[testing]" -U {opts} {packages}
@ -22,7 +22,6 @@ deps =
django-sendfile==0.3.6
Embedly
dj22: Django~=2.2.0
dj30: Django~=3.0.0
dj31: Django~=3.1.0
dj32: Django~=3.2.0

Wyświetl plik

@ -1,4 +1,3 @@
from django import VERSION as DJANGO_VERSION
from django.contrib.auth.models import Group, Permission
from django.http import HttpRequest, HttpResponse
from django.test import TestCase
@ -319,14 +318,9 @@ class TestPageCopy(TestCase, WagtailTestUtils):
self.assertEqual(response.status_code, 200)
# Check that a form error was raised
if DJANGO_VERSION >= (3, 0):
self.assertFormError(
response, 'form', 'new_slug', "Enter a valid “slug” consisting of Unicode letters, numbers, underscores, or hyphens."
)
else:
self.assertFormError(
response, 'form', 'new_slug', "Enter a valid 'slug' consisting of Unicode letters, numbers, underscores, or hyphens."
)
self.assertFormError(
response, 'form', 'new_slug', "Enter a valid “slug” consisting of Unicode letters, numbers, underscores, or hyphens."
)
def test_page_copy_post_valid_unicode_slug(self):
post_data = {

Wyświetl plik

@ -2,7 +2,6 @@ import unittest
import pytz
from django import VERSION as DJANGO_VERSION
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth import views as auth_views
@ -344,10 +343,7 @@ class TestAccountSection(TestCase, WagtailTestUtils, TestAccountSectionUtilsMixi
# Check that a validation error was raised
password_form = password_panel.get_form()
self.assertTrue('new_password2' in password_form.errors.keys())
if DJANGO_VERSION >= (3, 0):
self.assertTrue("The two password fields didnt match." in password_form.errors['new_password2'])
else:
self.assertTrue("The two password fields didn't match." in password_form.errors['new_password2'])
self.assertTrue("The two password fields didnt match." in password_form.errors['new_password2'])
# Check that the password was not changed
self.user.refresh_from_db()
@ -722,10 +718,7 @@ class TestPasswordReset(TestCase, WagtailTestUtils):
self.password_reset_uid = force_str(urlsafe_base64_encode(force_bytes(self.user.pk)))
# Create url_args
if DJANGO_VERSION >= (3, 0):
token = auth_views.PasswordResetConfirmView.reset_url_token
else:
token = auth_views.INTERNAL_RESET_URL_TOKEN
token = auth_views.PasswordResetConfirmView.reset_url_token
self.url_kwargs = dict(uidb64=self.password_reset_uid, token=token)
@ -807,11 +800,7 @@ class TestPasswordReset(TestCase, WagtailTestUtils):
# Check that a validation error was raised
self.assertTrue('new_password2' in response.context['form'].errors.keys())
if DJANGO_VERSION >= (3, 0):
self.assertTrue("The two password fields didnt match." in response.context['form'].errors['new_password2'])
else:
self.assertTrue("The two password fields didn't match." in response.context['form'].errors['new_password2'])
self.assertTrue("The two password fields didnt match." in response.context['form'].errors['new_password2'])
# Check that the password was not changed
self.assertTrue(get_user_model().objects.get(email='test@email.com').check_password('password'))

Wyświetl plik

@ -1,6 +1,5 @@
from datetime import timedelta
from django import VERSION as DJANGO_VERSION
from django.contrib.auth.models import Group, Permission
from django.test import TestCase
from django.urls import reverse
@ -85,30 +84,17 @@ class TestAuditLogAdmin(TestCase, WagtailTestUtils):
self.assertContains(response, "Page scheduled for publishing", 1)
self.assertContains(response, "Published", 1)
if DJANGO_VERSION >= (3, 0):
self.assertContains(
response, "Added the &#x27;Private, accessible to logged-in users&#x27; view restriction"
)
self.assertContains(
response,
"Updated the view restriction to &#x27;Private, accessible with the following password&#x27;"
)
self.assertContains(
response,
"Removed the &#x27;Private, accessible with the following password&#x27; view restriction"
)
else:
self.assertContains(
response, "Added the &#39;Private, accessible to logged-in users&#39; view restriction"
)
self.assertContains(
response,
"Updated the view restriction to &#39;Private, accessible with the following password&#39;"
)
self.assertContains(
response,
"Removed the &#39;Private, accessible with the following password&#39; view restriction"
)
self.assertContains(
response, "Added the &#x27;Private, accessible to logged-in users&#x27; view restriction"
)
self.assertContains(
response,
"Updated the view restriction to &#x27;Private, accessible with the following password&#x27;"
)
self.assertContains(
response,
"Removed the &#x27;Private, accessible with the following password&#x27; view restriction"
)
self.assertContains(response, 'system', 2) # create without a user + remove restriction
self.assertContains(response, 'the_editor', 9) # 7 entries by editor + 1 in sidebar menu + 1 in filter

Wyświetl plik

@ -126,7 +126,7 @@ class ModelAdmin(WagtailRegisterable):
self.model, self.inspect_view_enabled)
self.url_helper = self.get_url_helper_class()(self.model)
# Needed to support RelatedFieldListFilter in Django 2.2+
# Needed to support RelatedFieldListFilter
# See: https://github.com/wagtail/wagtail/issues/5105
self.admin_site = default_django_admin_site

Wyświetl plik

@ -1,4 +1,3 @@
from django import VERSION as DJANGO_VERSION
from django.contrib.auth.models import Group, Permission
from django.test import TestCase
@ -65,21 +64,13 @@ class TestExcludeFromExplorer(TestCase, WagtailTestUtils):
def test_attribute_effects_explorer(self):
# The two VenuePages should appear in the venuepage list
response = self.client.get('/admin/modeladmintest/venuepage/')
if DJANGO_VERSION >= (3, 0):
self.assertContains(response, "Santa&#x27;s Grotto")
self.assertContains(response, "Santa&#x27;s Workshop")
else:
self.assertContains(response, "Santa&#39;s Grotto")
self.assertContains(response, "Santa&#39;s Workshop")
self.assertContains(response, "Santa&#x27;s Grotto")
self.assertContains(response, "Santa&#x27;s Workshop")
# But when viewing the children of 'Christmas' event in explorer
response = self.client.get('/admin/pages/4/')
if DJANGO_VERSION >= (3, 0):
self.assertNotContains(response, "Santa&#x27;s Grotto")
self.assertNotContains(response, "Santa&#x27;s Workshop")
else:
self.assertNotContains(response, "Santa&#39;s Grotto")
self.assertNotContains(response, "Santa&#39;s Workshop")
self.assertNotContains(response, "Santa&#x27;s Grotto")
self.assertNotContains(response, "Santa&#x27;s Workshop")
# But the other test page should...
self.assertContains(response, "Claim your free present!")

Wyświetl plik

@ -33,16 +33,12 @@ from wagtail.admin.views.mixins import SpreadsheetExportMixin
from .forms import ParentChooserForm
try:
from django.db.models.sql.constants import QUERY_TERMS
except ImportError:
# Django 2.1+ does not have QUERY_TERMS anymore
QUERY_TERMS = {
'contains', 'day', 'endswith', 'exact', 'gt', 'gte', 'hour',
'icontains', 'iendswith', 'iexact', 'in', 'iregex', 'isnull',
'istartswith', 'lt', 'lte', 'minute', 'month', 'range', 'regex',
'search', 'second', 'startswith', 'week_day', 'year',
}
QUERY_TERMS = {
'contains', 'day', 'endswith', 'exact', 'gt', 'gte', 'hour',
'icontains', 'iendswith', 'iexact', 'in', 'iregex', 'isnull',
'istartswith', 'lt', 'lte', 'minute', 'month', 'range', 'regex',
'search', 'second', 'startswith', 'week_day', 'year',
}
class WMABaseView(TemplateView):
@ -255,7 +251,7 @@ class IndexView(SpreadsheetExportMixin, WMABaseView):
IGNORED_PARAMS = (ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, EXPORT_VAR)
# sortable_by is required by the django.contrib.admin.templatetags.admin_list.result_headers
# template tag as of Django 2.1 - see https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.sortable_by
# template tag - see https://docs.djangoproject.com/en/stable/ref/contrib/admin/#django.contrib.admin.ModelAdmin.sortable_by
sortable_by = None
@method_decorator(login_required)

Wyświetl plik

@ -7,7 +7,6 @@ from collections import namedtuple
from io import StringIO
from urllib.parse import urlparse
from django import VERSION as DJANGO_VERSION
from django import forms
from django.apps import apps
from django.conf import settings
@ -96,17 +95,13 @@ def _extract_field_data(source, exclude_fields=None):
if isinstance(field, models.OneToOneField) and field.remote_field.parent_link:
continue
if DJANGO_VERSION >= (3, 0) and isinstance(field, models.ForeignKey):
if isinstance(field, models.ForeignKey):
# Use attname to copy the ID instead of retrieving the instance
# Note: We first need to set the field to None to unset any object
# that's there already just setting _id on its own won't change the
# field until its saved.
# Before Django 3.0, Django won't find the new object if the field
# was set to None in this way, so this optimisation isn't available
# for Django 2.x.
data_dict[field.name] = None
data_dict[field.attname] = getattr(source, field.attname)

Wyświetl plik

@ -2,18 +2,13 @@ from django.conf import settings
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.http import url_has_allowed_host_and_scheme
from wagtail.core import hooks
from wagtail.core.forms import PasswordViewRestrictionForm
from wagtail.core.models import Page, PageViewRestriction, Site
try:
from django.utils.http import url_has_allowed_host_and_scheme
except ImportError: # fallback for Django 2.2
from django.utils.http import is_safe_url as url_has_allowed_host_and_scheme
def serve(request, path):
# we need a valid Site object corresponding to this request in order to proceed
site = Site.find_for_request(request)

Wyświetl plik

@ -5,6 +5,7 @@ from django.http import Http404, HttpResponse, StreamingHttpResponse
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils.http import url_has_allowed_host_and_scheme
from django.views.decorators.cache import cache_control
from django.views.decorators.http import etag
@ -17,12 +18,6 @@ from wagtail.utils import sendfile_streaming_backend
from wagtail.utils.sendfile import sendfile
try:
from django.utils.http import url_has_allowed_host_and_scheme
except ImportError: # fallback for Django 2.2
from django.utils.http import is_safe_url as url_has_allowed_host_and_scheme
def document_etag(request, document_id, document_filename):
Document = get_document_model()
if hasattr(Document, 'file_hash'):