10000 feat: django 5 support for cms 3.11 by protoroto · Pull Request #7724 · django-cms/django-cms · GitHub
[go: up one dir, main page]

Skip to content

feat: django 5 support for cms 3.11 #7724

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: django 5's choice widget is not lazy (#7707)
* Support for Django 5.0

* Fix: test.yml and django Promise handling

* Shorten github action names

* Update test.yml

* Update _cms.scss

* Update setup.py

* Fix: Django 5 choice widget is not lazy either

* Add test

* Fix: Swapped underscore

* Deprecate SuperLazyIterator and LazyChoiceField
  • Loading branch information
fsbraun authored and marksweb committed Dec 21, 2023
commit 40c93b53a036d7ad5942a16cd273033fc7ba10d0
27 changes: 20 additions & 7 deletions cms/forms/fields.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import warnings

from django import forms
from django.contrib.admin.widgets import RelatedFieldWidgetWrapper
from django.core.validators import EMPTY_VALUES
from django.forms import ChoiceField
from django.utils.translation import gettext_lazy as _

from cms.forms.utils import get_page_choices, get_site_choices
from cms.forms.validators import validate_url_extra
from cms.forms.widgets import PageSelectWidget, PageSmartLinkWidget
from cms.models.pagemodel import Page
from cms.utils.compat import DJANGO_4_2


class SuperLazyIterator:
def __init__(self, func):
warnings.warn("SuperLazyIterator is deprecated.",
DeprecationWarning, stacklevel=2)
self.func = func

def __iter__(self):
Expand All @@ -19,14 +25,23 @@ def __iter__(self):

class LazyChoiceField(forms.ChoiceField):

def __init__(self, *args, **kwargs):
warnings.warn("LazyChoiceField is deprecated. Use Django's ChoiceField instead.",
DeprecationWarning, stacklevel=2)
super().__init__(*args, **kwargs)

@property
def choices(self):
return super().choices()

@choices.setter
def _set_choices(self, value):
# we overwrite this function so no list(value) is called
self._choices = self.widget.choices = value
def choices(self, value):
# we overwrite this function so no list(value) or normalize_choices(value) is called
# also, do not call the widget's setter as of Django 5
if DJANGO_4_2:
self._choices = self.widget.choices = value
else:
self._choices = self.widget._choices = value


class PageSelectFormField(forms.MultiValueField):
Expand All @@ -42,14 +57,12 @@ def __init__(self, queryset=None, empty_label="---------", cache_choices=False,
errors = self.default_error_messages.copy()
if 'error_messages' in kwargs:
errors.update(kwargs['error_messages'])
site_choices = SuperLazyIterator(get_site_choices)
page_choices = SuperLazyIterator(get_page_choices)
self.limit_choices_to = limit_choices_to
kwargs['required'] = required
kwargs.pop('blank', None)
fields = (
LazyChoiceField(choices=site_choices, required=False, error_messages={'invalid': errors['invalid_site']}),
LazyChoiceField(choices=page_choices, required=False, error_messages={'invalid': errors['invalid_page']}),
ChoiceField(choices=get_site_choices, required=False, error_messages={'invalid': errors['invalid_site']}),
ChoiceField(choices=get_page_choices, required=False, error_messages={'invalid': errors['invalid_page']}),
)
super().__init__(fields, *args, **kwargs)

Expand Down
11 changes: 11 additions & 0 deletions cms/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,17 @@ def test_superlazy_iterator_behaves_properly_for_pages(self):

self.assertEqual(normal_result, list(lazy_result))

def test_lazy_choice_field_behaves_properly(self):
"""Ensure LazyChoiceField is really lazy"""
choices_called = False
def get_choices():
nonlocal choices_called
choices_called = True
return ("", "-----"),

LazyChoiceField(choices=SuperLazyIterator(get_choices))
self.assertFalse(choices_called, "Lazy choice function called")


class PermissionFormTestCase(CMSTestCase):

Expand Down
0