From 31c02198804ca6775a4cfa7d9ed04bd238e70a4d Mon Sep 17 00:00:00 2001 From: Dino Perovic Date: Fri, 5 May 2023 15:20:18 +0200 Subject: [PATCH] Bump Django to 4.2 and Wagtail to 5.0 - Django supported versions are 4.1, 4.2 - Wagtail supported versions are 4.0, 5.0 - removed unnecesary usage of pragma no-cover - dropped support for older Django and Wagtail --- .github/workflows/publish.yml | 4 +-- .github/workflows/test.yml | 21 +++++------ docs/reference/admin.rst | 6 ++-- docs/releases/1.2.0.rst | 18 ++++++++++ docs/releases/dev.rst | 11 ------ docs/releases/index.rst | 8 ++++- example/project/settings.py | 2 +- example/project/urls.py | 2 +- example/tests/admin/test_admin_panels.py | 4 +-- .../tests/admin/test_admin_wagtail_hooks.py | 18 +++++----- pyproject.toml | 13 +++---- salesman/admin/wagtail/edit_handlers.py | 1 - salesman/admin/wagtail/mixins.py | 2 +- salesman/admin/wagtail/panels.py | 35 ++++++++----------- salesman/admin/wagtail/views.py | 2 +- salesman/admin/wagtail_hooks.py | 6 ++-- salesman/checkout/serializers.py | 2 +- salesman/orders/serializers.py | 2 +- 18 files changed, 81 insertions(+), 76 deletions(-) create mode 100644 docs/releases/1.2.0.rst delete mode 100644 docs/releases/dev.rst delete mode 100644 salesman/admin/wagtail/edit_handlers.py diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c91a669..ca66b4d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,11 +13,11 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.x' + python-version: "3.x" - name: Install dependencies run: | python -m pip install --upgrade pip - pip install poetry~=1.1.0 + pip install poetry~=1.4.0 poetry config virtualenvs.create false poetry install --no-dev - name: Build and publish diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 43c27ba..4e0a04b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,12 +4,12 @@ on: push: branches: - master - - 'release/**' + - "release/**" paths: - - '**.py' + - "**.py" pull_request: paths: - - '**.py' + - "**.py" jobs: lint: @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: - python-version: '3.8' + python-version: "3.11" - uses: pre-commit/action@v2.0.3 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -30,11 +30,12 @@ jobs: needs: lint strategy: matrix: - python-version: ['3.8', '3.9', '3.10'] - django-version: ['3.1', '3.2', '4.0'] + python-version: ["3.8", "3.9", "3.10", "3.11"] + django-version: ["4.1", "4.2"] + wagtail-version: ["4.0", "5.0"] include: - - python-version: '3.10' - django-version: '4.0' + - python-version: "3.11" + django-version: "4.2" codecov: true steps: - uses: actions/checkout@v2 @@ -42,10 +43,10 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies with Django ${{ matrix.django-version }} + - name: Install dependencies Django-${{ matrix.django-version }} Wagtail-${{ matrix.wagtail-version }} run: | python -m pip install --upgrade pip - pip install poetry~=1.1.0 django~=${{ matrix.django-version }}.0 + pip install poetry~=1.4.0 Django~=${{ matrix.django-version }}.0 Wagtail~=${{ matrix.wagtail-version }} poetry config virtualenvs.create false poetry install --no-dev -E tests - name: Test with pytest diff --git a/docs/reference/admin.rst b/docs/reference/admin.rst index 363eea0..077d0ca 100644 --- a/docs/reference/admin.rst +++ b/docs/reference/admin.rst @@ -51,10 +51,10 @@ Widgets Wagtail ======= -Edit handlers -------------- +Panels +------ -.. automodule:: salesman.admin.wagtail.edit_handlers +.. automodule:: salesman.admin.wagtail.panels :members: Forms diff --git a/docs/releases/1.2.0.rst b/docs/releases/1.2.0.rst new file mode 100644 index 0000000..713d11e --- /dev/null +++ b/docs/releases/1.2.0.rst @@ -0,0 +1,18 @@ +##### +1.2.0 +##### + +*TBA* + +Added +----- + +- Added support for Django `4.2` +- Added support for Wagtail `5.0` +- Added option to disable anonymous checkout using ``SALESMAN_ALLOW_ANONYMOUS_USER_CHECKOUT`` setting. (`@laricko `_) + +Removed +------- + +- Removed support for Django `3.1`, `3.2` and `4.0` +- Removed support for Wagtail `2.0` and `3.0` diff --git a/docs/releases/dev.rst b/docs/releases/dev.rst deleted file mode 100644 index 04e990b..0000000 --- a/docs/releases/dev.rst +++ /dev/null @@ -1,11 +0,0 @@ -##### -In development -##### - -*TBA* - -Added ------ - -- Added support for ``Wagtail 4.2`` -- Added option to disable anonymous checkout using ``SALESMAN_ALLOW_ANONYMOUS_USER_CHECKOUT`` setting. (`@laricko `_) diff --git a/docs/releases/index.rst b/docs/releases/index.rst index 67dd20e..ccccd01 100644 --- a/docs/releases/index.rst +++ b/docs/releases/index.rst @@ -14,11 +14,17 @@ Release notes and upgrade information. This project adheres to - ``Fixed`` for any bug fixes. - ``Security`` in case of vulnerabilities. +.. toctree:: + :caption: v1.2 + :maxdepth: 1 + + 1.2.0 + + .. toctree:: :caption: v1.1 :maxdepth: 1 - dev 1.1.6 1.1.5 1.1.4 diff --git a/example/project/settings.py b/example/project/settings.py index a4e46a6..04cad19 100644 --- a/example/project/settings.py +++ b/example/project/settings.py @@ -67,7 +67,7 @@ "wagtail.images", "wagtail.search", "wagtail.admin", - "wagtail.core", + "wagtail", "modelcluster", "taggit", # shop diff --git a/example/project/urls.py b/example/project/urls.py index e19bd23..a01a4db 100644 --- a/example/project/urls.py +++ b/example/project/urls.py @@ -17,8 +17,8 @@ from django.conf.urls.static import static from django.contrib import admin from django.urls import include, path, re_path +from wagtail import urls as wagtail_urls from wagtail.admin import urls as wagtailadmin_urls -from wagtail.core import urls as wagtail_urls from wagtail.documents import urls as wagtaildocs_urls urlpatterns = [ diff --git a/example/tests/admin/test_admin_panels.py b/example/tests/admin/test_admin_panels.py index d3458e3..37ddf69 100644 --- a/example/tests/admin/test_admin_panels.py +++ b/example/tests/admin/test_admin_panels.py @@ -7,14 +7,14 @@ from salesman.admin import utils from salesman.admin.mixins import OrderAdminMixin -from salesman.admin.wagtail.edit_handlers import ( +from salesman.admin.wagtail.forms import WagtailOrderModelForm +from salesman.admin.wagtail.panels import ( OrderAdminPanel, OrderCheckboxPanel, OrderDatePanel, OrderItemsPanel, ReadOnlyPanel, ) -from salesman.admin.wagtail.forms import WagtailOrderModelForm from salesman.admin.wagtail_hooks import OrderAdmin from salesman.core.utils import get_salesman_model from shop.models import Product diff --git a/example/tests/admin/test_admin_wagtail_hooks.py b/example/tests/admin/test_admin_wagtail_hooks.py index 672bd2a..746f0ab 100644 --- a/example/tests/admin/test_admin_wagtail_hooks.py +++ b/example/tests/admin/test_admin_wagtail_hooks.py @@ -1,7 +1,7 @@ import pytest from django.contrib.admin.sites import AdminSite from django.contrib.messages.storage.fallback import FallbackStorage -from wagtail.admin.edit_handlers import EditHandler, FieldPanel, ObjectList +from wagtail.admin.panels import FieldPanel, ObjectList, Panel from salesman.admin import wagtail_hooks from salesman.core.utils import get_salesman_model @@ -78,20 +78,20 @@ def test_order_admin(rf, client, django_user_model): assert view.get_meta_title() == "Confirm Order refund" # test get_edit_handler - edit_handler = modeladmin.get_edit_handler(order, request) + edit_handler = modeladmin.get_edit_handler() assert edit_handler == modeladmin.default_edit_handler modeladmin.default_edit_handler = None - edit_handler = modeladmin.get_edit_handler(order, request) + edit_handler = modeladmin.get_edit_handler() assert isinstance(edit_handler, ObjectList) modeladmin.model.panels = [FieldPanel("model_panel")] - edit_handler = modeladmin.get_edit_handler(order, request) + edit_handler = modeladmin.get_edit_handler() assert edit_handler.children == modeladmin.model.panels - modeladmin.model.edit_handler = EditHandler(heading="model_edit_handler") - edit_handler = modeladmin.get_edit_handler(order, request) + modeladmin.model.edit_handler = Panel(heading="model_edit_handler") + edit_handler = modeladmin.get_edit_handler() assert edit_handler == modeladmin.model.edit_handler modeladmin.panels = [FieldPanel("admin_panel")] - edit_handler = modeladmin.get_edit_handler(order, request) + edit_handler = modeladmin.get_edit_handler() assert edit_handler.children == modeladmin.panels - modeladmin.edit_handler = EditHandler(heading="admin_edit_handler") - edit_handler = modeladmin.get_edit_handler(order, request) + modeladmin.edit_handler = Panel(heading="admin_edit_handler") + edit_handler = modeladmin.get_edit_handler() assert edit_handler == modeladmin.edit_handler diff --git a/pyproject.toml b/pyproject.toml index 4e5983c..8e64da6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,14 +12,11 @@ keywords = ["e-commerce", "headless", "rest-api", "shop", "framework"] classifiers = [ "Development Status :: 5 - Production/Stable", "Framework :: Django", - "Framework :: Django :: 3.1", - "Framework :: Django :: 3.2", - "Framework :: Django :: 4.0", "Framework :: Django :: 4.1", + "Framework :: Django :: 4.2", "Framework :: Wagtail", - "Framework :: Wagtail :: 2", - "Framework :: Wagtail :: 3", "Framework :: Wagtail :: 4", + "Framework :: Wagtail :: 5", "Intended Audience :: Developers", "Operating System :: OS Independent", "Topic :: Internet", @@ -31,12 +28,12 @@ include = ["LICENSE"] [tool.poetry.dependencies] python = ">=3.8.1,<4.0" -django = ">=3.1,<4.2" -djangorestframework = ">=3.11,<3.15" +django = ">=4.1.3,<4.3" +djangorestframework = ">=3.11.1,<4.0" # Optional Pygments = {version = "^2.6", optional = true} -wagtail = {version = ">=2.9,<4.3", optional = true} +wagtail = {version = ">=4.0,<6.0", optional = true} pytest = {version = "~7.0.0", optional = true} pytest-django = {version = "~4.5.0", optional = true} pytest-cov = {version = "~3.0.0", optional = true} diff --git a/salesman/admin/wagtail/edit_handlers.py b/salesman/admin/wagtail/edit_handlers.py deleted file mode 100644 index c6d8746..0000000 --- a/salesman/admin/wagtail/edit_handlers.py +++ /dev/null @@ -1 +0,0 @@ -from .panels import * # noqa diff --git a/salesman/admin/wagtail/mixins.py b/salesman/admin/wagtail/mixins.py index fd13fab..0354d46 100644 --- a/salesman/admin/wagtail/mixins.py +++ b/salesman/admin/wagtail/mixins.py @@ -6,7 +6,7 @@ from django.utils.html import format_html from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ -from wagtail.admin.edit_handlers import ( +from wagtail.admin.panels import ( FieldPanel, InlinePanel, MultiFieldPanel, diff --git a/salesman/admin/wagtail/panels.py b/salesman/admin/wagtail/panels.py index 69a9e2e..78ef2d2 100644 --- a/salesman/admin/wagtail/panels.py +++ b/salesman/admin/wagtail/panels.py @@ -8,17 +8,12 @@ from django.utils.html import format_html from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ -from wagtail.admin.edit_handlers import EditHandler as Panel -from wagtail.utils.version import get_main_version as get_wagtail_version +from wagtail.admin.panels import Panel from salesman.conf import app_settings from ..utils import format_price -if get_wagtail_version() < "3.0.0": # pragma: no cover - # Attach dummy BoundPanel class for older Wagtail versions - Panel.BoundPanel = object - class ReadOnlyPanel(Panel): """ @@ -59,22 +54,22 @@ def on_model_bound(self) -> None: if field and not self.help_text: self.help_text: str = getattr(field, "help_text", "") - def get_value(self) -> Any: # pragma: no cover + def get_value(self) -> Any: value = getattr(self.instance, self.attr) if callable(value): value = value(self.instance) return value - def format_value(self, value: Any) -> Any: # pragma: no cover + def format_value(self, value: Any) -> Any: if self.formatter and value is not None: value = self.formatter(value, self.instance, self.request) return value - def render(self) -> Any: # pragma: no cover + def render(self) -> Any: value = self.get_value() return self.format_value(value) - def render_as_object(self) -> Any: # pragma: no cover + def render_as_object(self) -> Any: if self.renderer: return self.renderer(self.get_value(), self.instance, self.request) return format_html( @@ -87,7 +82,7 @@ def render_as_object(self) -> Any: # pragma: no cover self.render(), ) - def render_as_field(self) -> Any: # pragma: no cover + def render_as_field(self) -> Any: if self.renderer: return self.renderer(self.get_value(), self.instance, self.request) help_html = ( @@ -184,7 +179,7 @@ def render_as_field(self) -> Any: class OrderDatePanel(ReadOnlyPanel): - def format_value(self, value: Any) -> Any: # pragma: no cover + def format_value(self, value: Any) -> Any: if value: value = date_format(value, format="DATETIME_FORMAT") return value @@ -197,7 +192,7 @@ def format_value(self, value: Any) -> Any: class OrderCheckboxPanel(ReadOnlyPanel): - def format_value(self, value: Any) -> str: # pragma: no cover + def format_value(self, value: Any) -> str: icon, color = ("tick", "#157b57") if value else ("cross", "#cd3238") template = '' return format_html(template, icon, color) @@ -210,13 +205,13 @@ def format_value(self, value: Any) -> str: class OrderItemsPanel(ReadOnlyPanel): - def classes(self) -> list[str]: # pragma: no cover + def classes(self) -> list[str]: return ["salesman-order-items"] - def render_as_field(self) -> str: # pragma: no cover + def render_as_field(self) -> str: return self.render() - def render_as_object(self) -> str: # pragma: no cover + def render_as_object(self) -> str: return self.render() def format_json( @@ -224,12 +219,12 @@ def format_json( value: dict[str, Any], obj: Any, request: HttpRequest, - ) -> str: # pragma: no cover + ) -> str: return app_settings.SALESMAN_ADMIN_JSON_FORMATTER( value, context={"order_item": True} ) - def render(self) -> str: # pragma: no cover + def render(self) -> str: head = f""" {_('Name')} {_('Code')} @@ -323,7 +318,7 @@ class OrderAdminPanel(ReadOnlyPanel): def on_model_bound(self) -> None: pass - def on_form_bound(self) -> None: # pragma: no cover + def on_form_bound(self) -> None: if not hasattr(self.form, "model_admin"): raise AssertionError("OrderAdminPanel can only be used in OrderModelAdmin.") @@ -332,7 +327,7 @@ def on_form_bound(self) -> None: # pragma: no cover if heading and not self.heading: self.heading = heading - def get_value(self) -> Any: # pragma: no cover + def get_value(self) -> Any: return getattr(self.form.model_admin, self.attr)(self.instance) class BoundPanel(ReadOnlyPanel.BoundPanel): diff --git a/salesman/admin/wagtail/views.py b/salesman/admin/wagtail/views.py index b4a9098..ba549aa 100644 --- a/salesman/admin/wagtail/views.py +++ b/salesman/admin/wagtail/views.py @@ -43,7 +43,7 @@ def get_meta_title(self) -> str: def refund_url(self) -> str | None: try: return str(self.url_helper.get_action_url("refund", self.pk_quoted)) - except NoReverseMatch: # pragma: no cover + except NoReverseMatch: return None diff --git a/salesman/admin/wagtail_hooks.py b/salesman/admin/wagtail_hooks.py index e8aa231..024d4e8 100644 --- a/salesman/admin/wagtail_hooks.py +++ b/salesman/admin/wagtail_hooks.py @@ -2,7 +2,7 @@ from typing import Any, Type -from wagtail.admin.edit_handlers import EditHandler, ObjectList +from wagtail.admin.panels import ObjectList, Panel from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register from salesman.conf import app_settings @@ -61,7 +61,7 @@ def get_base_form_class( {"model_admin": self}, ) - def get_edit_handler(self, *args: Any, **kwargs: Any) -> EditHandler: + def get_edit_handler(self) -> Panel: """ Returns edit handler with custom base form class attached. @@ -81,7 +81,7 @@ def get_edit_handler(self, *args: Any, **kwargs: Any) -> EditHandler: elif hasattr(self, "default_edit_handler") and self.default_edit_handler: edit_handler = self.default_edit_handler else: - edit_handler = super().get_edit_handler(*args, **kwargs) + edit_handler = super().get_edit_handler() edit_handler.base_form_class = self.get_base_form_class( form_class=getattr(edit_handler, "base_form_class", None) diff --git a/salesman/checkout/serializers.py b/salesman/checkout/serializers.py index 598cade..28de8a8 100644 --- a/salesman/checkout/serializers.py +++ b/salesman/checkout/serializers.py @@ -85,7 +85,7 @@ def validate_payment_method(self, value: str) -> PaymentMethod | None: if payment: payment.validate_basket(basket, request) return payment - return None # pragma: no cover + return None def validate_extra(self, value: dict[str, Any]) -> dict[str, Any]: # Update basket `extra` instead of replacing it, remove null values. diff --git a/salesman/orders/serializers.py b/salesman/orders/serializers.py index ce91e33..f437afc 100644 --- a/salesman/orders/serializers.py +++ b/salesman/orders/serializers.py @@ -200,7 +200,7 @@ def validate_payment_method(self, value: str) -> PaymentMethod | None: if payment: payment.validate_order(order, request) return payment - return None # pragma: no cover + return None def save(self, **kwargs: Any) -> None: # Process the payment.