diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b159cb8f..eb395266 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] db: ['sqlite'] steps: @@ -62,7 +62,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] db: ['postgres'] services: diff --git a/README.md b/README.md index 759171e8..5c1adc33 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,8 @@ Getting Grapple installed is designed to be as simple as possible! ``` Python >= 3.8 -Wagtail >= 4.1 +Wagtail >= 5.2 +Django >= 4.2 ``` ### Installation @@ -180,8 +181,8 @@ Any contributions [you make](https://github.com/torchbox/wagtail-grapple/graphs/ Wagtail Grapple supports: -- Python 3.8, 3.9, 3.10 and 3.11 -- Wagtail >= 4.1 +- Python 3.8, 3.9, 3.10 3.11 and 3.12 +- Wagtail >= 5.2 ## License diff --git a/grapple/utils.py b/grapple/utils.py index 3130a767..94cf74b0 100644 --- a/grapple/utils.py +++ b/grapple/utils.py @@ -1,17 +1,30 @@ from typing import Literal, Optional from django.conf import settings +from django.core.exceptions import ImproperlyConfigured from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db import connection from graphql import GraphQLError +from wagtail import VERSION as WAGTAIL_VERSION from wagtail.models import Site from wagtail.search.index import class_is_indexed -from wagtail.search.models import Query from .settings import grapple_settings from .types.structures import BasePaginatedType, PaginationType +if grapple_settings.ADD_SEARCH_HIT: + if WAGTAIL_VERSION >= (6, 0): + try: + from wagtail.contrib.search_promotions.models import Query + except ImportError as e: + raise ImproperlyConfigured( + "wagtail.contrib.search_promotions must be installed if grapple_settings.ADD_SEARCH_HIT=True and using Wagtail >= 6.0" + ) from e + else: + from wagtail.search.models import Query + + def resolve_site_by_id( *, id: int, diff --git a/pyproject.toml b/pyproject.toml index ebc2180d..973d7a39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,14 +25,15 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Framework :: Wagtail", - "Framework :: Wagtail :: 4", "Framework :: Wagtail :: 5", + "Framework :: Wagtail :: 6", ] dynamic = ["version"] requires-python = ">=3.8" dependencies = [ - "Wagtail>=4.1", + "Wagtail>=5.2", "graphene-django>=3,<4", "wagtail-headless-preview" ] diff --git a/tests/requirements.txt b/tests/requirements.txt index f00cfbad..59135be2 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -3,7 +3,7 @@ black>=23.9.1 ruff==0.0.287 # Runtime requirements -Django>=3.2,<5.0 +Django>=4.2,<5.1 wagtail>=4.1 graphene-django>=3.0.0 factory-boy==3.2.1 diff --git a/tests/settings.py b/tests/settings.py index 54beee43..fca113b8 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -15,6 +15,8 @@ import dj_database_url +from wagtail import VERSION as WAGTAIL_VERSION + BASE_DIR = pathlib.Path(__file__).parents[0] @@ -54,6 +56,9 @@ "graphene_django", ] +if WAGTAIL_VERSION >= (6, 0): + INSTALLED_APPS.append("wagtail.contrib.search_promotions") + MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", diff --git a/tests/test_blog.py b/tests/test_blog.py index 936004ce..c43cf012 100644 --- a/tests/test_blog.py +++ b/tests/test_blog.py @@ -500,7 +500,8 @@ def test_blog_embed(self): "height": 113, "html": '', + 'picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen ' + 'title="Wagtail Space 2018">', } for block in body: if block["blockType"] == "VideoBlock": diff --git a/tests/testapp/migrations/0001_initial.py b/tests/testapp/migrations/0001_initial.py index 8a266d71..d09e18b1 100644 --- a/tests/testapp/migrations/0001_initial.py +++ b/tests/testapp/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.10 on 2023-08-30 13:29 +# Generated by Django 4.2 on 2024-04-11 15:33 import django.db.models.deletion import modelcluster.contrib.taggit @@ -8,6 +8,7 @@ import wagtail.embeds.blocks import wagtail.fields import wagtail.images.blocks +import wagtail.images.models import wagtail.models.collections import wagtail.search.index import wagtail.snippets.blocks @@ -15,22 +16,16 @@ from django.conf import settings from django.db import migrations, models -from wagtail import VERSION as WAGTAIL_VERSION - - -if WAGTAIL_VERSION < (4, 2): - from django.db.models import ImageField as ImageField -else: - from wagtail.images.models import WagtailImageField as ImageField class Migration(migrations.Migration): initial = True dependencies = [ - ("wagtailcore", "0078_referenceindex"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("taggit", "0005_auto_20220424_2025"), ("wagtailmedia", "0004_duration_optional_floatfield"), + ("wagtailcore", "0089_log_entry_data_json_null_to_object"), ] operations = [ @@ -276,6 +271,12 @@ class Migration(migrations.Migration): "testapp.Person" ), ), + ( + "custom_interface_block", + wagtail.blocks.StructBlock( + [("custom_text", wagtail.blocks.TextBlock())] + ), + ), ], use_json_field=True, ), @@ -324,7 +325,7 @@ class Migration(migrations.Migration): ("title", models.CharField(max_length=255, verbose_name="title")), ( "file", - models.ImageField( + wagtail.images.models.WagtailImageField( height_field="height", upload_to=wagtail.images.models.get_upload_to, verbose_name="file", @@ -766,8 +767,9 @@ class Migration(migrations.Migration): ("filter_spec", models.CharField(db_index=True, max_length=255)), ( "file", - ImageField( + wagtail.images.models.WagtailImageField( height_field="height", + storage=wagtail.images.models.get_rendition_storage, upload_to=wagtail.images.models.get_rendition_upload_to, width_field="width", ), diff --git a/tox.ini b/tox.ini index d8c21dc7..589f0915 100644 --- a/tox.ini +++ b/tox.ini @@ -2,8 +2,8 @@ min_version = 4.0 envlist = - py{38,39,310}-django{32,41}-wagtail{41,50,51} - py{311}-django{41,42}-wagtail{50,51} + py{38,39,310,311,312}-django{42}-wagtail{52,60} + py{310,311,312}-django{50}-wagtail{52,60} interactive [gh-actions] @@ -12,6 +12,7 @@ python = 3.9: py39 3.10: py310 3.11: py311 + 3.12: py312 [gh-actions:env] DB = @@ -42,13 +43,11 @@ deps = dj-database-url==2.1.0 psycopg2>=2.9.5,<3.0.0 - django32: Django>=3.2,<3.3 - django41: Django>=4.1,<4.2 django42: Django>=4.2,<5.0 - wagtail41: wagtail>=4.1,<4.2 - wagtail50: wagtail>=5.0,<5.1 - wagtail51: wagtail>=5.1,<5.2 - interactive: wagtail>=4.1 + django50: Django>=5.0,<5.1 + wagtail52: wagtail>=5.2,<6.0 + wagtail60: wagtail>=6.0,<6.1 + interactive: wagtail>=5.2 install_command = python -Im pip install -U {opts} {packages} @@ -77,7 +76,7 @@ description = An interactive environment for local testing purposes base_python = python3.11 deps = - wagtail>=4.1 + wagtail>=5.2 commands_pre = python manage.py makemigrations