Skip to content
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

Feat/django 42 compatible updated #3

Merged
merged 7 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:

services:
mysql:
image: mysql:5.7
image: mysql:8.0
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: djangocms_test
Expand Down
1 change: 1 addition & 0 deletions cms/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__version__ = '4.0.1.dev2'

default_app_config = 'cms.apps.CMSConfig'
3 changes: 0 additions & 3 deletions cms/admin/pageadmin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections import namedtuple
import copy
import json

import django
Expand Down Expand Up @@ -907,8 +906,6 @@ def duplicate(self, request, object_id):
if obj is None:
raise self._get_404_exception(object_id)

request = copy.copy(request)

if request.method == 'GET':
# source is a field in the form
# because its value is in the url,
Expand Down
73 changes: 57 additions & 16 deletions cms/middleware/language.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,63 @@
import datetime

from django.utils.translation import get_language
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
from django.utils.translation import get_language

from cms.utils.compat import DJANGO_2_2

if DJANGO_2_2:
from django.utils.translation import LANGUAGE_SESSION_KEY


class LanguageCookieMiddleware(MiddlewareMixin):
def process_response(self, request, response):
language = get_language()
if hasattr(request, 'session'):
session_language = request.session.get(LANGUAGE_SESSION_KEY, None)
if session_language and not session_language == language:
request.session[LANGUAGE_SESSION_KEY] = language
request.session.save()
if settings.LANGUAGE_COOKIE_NAME in request.COOKIES and \
request.COOKIES[settings.LANGUAGE_COOKIE_NAME] == language:
def __init__(self, get_response):
super().__init__(get_response)

if DJANGO_2_2:

def __call__(self, request):
response = self.get_response(request)
language = get_language()
if hasattr(request, 'session'):
session_language = request.session.get(LANGUAGE_SESSION_KEY, None)
if session_language and not session_language == language:
request.session[LANGUAGE_SESSION_KEY] = language
request.session.save()
if (
settings.LANGUAGE_COOKIE_NAME in request.COOKIES
and request.COOKIES[settings.LANGUAGE_COOKIE_NAME] == language # noqa: W503
):
return response
response.set_cookie(
settings.LANGUAGE_COOKIE_NAME,
value=language,
domain=settings.LANGUAGE_COOKIE_DOMAIN,
max_age=settings.LANGUAGE_COOKIE_AGE or 365 * 24 * 60 * 60, # 1 year
path=settings.LANGUAGE_COOKIE_PATH,
)
return response
else:

def __call__(self, request):
response = self.get_response(request)
language = get_language()
if (
settings.LANGUAGE_COOKIE_NAME in request.COOKIES # noqa: W503
and request.COOKIES[settings.LANGUAGE_COOKIE_NAME] == language
):
return response

# To ensure support of very old browsers, Django processed automatically "expires" according
# to max_age value.
# https://docs.djangoproject.com/en/3.2/ref/request-response/#django.http.HttpResponse.set_cookie

response.set_cookie(
settings.LANGUAGE_COOKIE_NAME,
value=language,
domain=settings.LANGUAGE_COOKIE_DOMAIN,
max_age=settings.LANGUAGE_COOKIE_AGE or 365 * 24 * 60 * 60, # 1 year
httponly=settings.LANGUAGE_COOKIE_HTTPONLY,
path=settings.LANGUAGE_COOKIE_PATH,
samesite=settings.LANGUAGE_COOKIE_SAMESITE,
secure=settings.LANGUAGE_COOKIE_SECURE,
)
return response
max_age = 365 * 24 * 60 * 60 # 10 years
expires = datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age)
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language, expires=expires)
return response
1 change: 1 addition & 0 deletions cms/test_utils/project/app_using_non_feature/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_using_non_feature.apps.NonFeatureCMSConfig'
1 change: 1 addition & 0 deletions cms/test_utils/project/app_with_bad_cms_file/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_with_bad_cms_file.apps.BadCMSFileConfig'
1 change: 1 addition & 0 deletions cms/test_utils/project/app_with_cms_config/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_with_cms_config.apps.CMSConfigConfig'
1 change: 1 addition & 0 deletions cms/test_utils/project/app_with_cms_feature/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_with_cms_feature.apps.CMSFeatureConfig'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_with_cms_feature_and_config.apps.CMSFeatureAndConfigConfig'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_with_feature_not_implemented.apps.CMSFeatureConfig'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_with_two_cms_config_classes.apps.TwoCMSAppClassesConfig'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_with_two_cms_feature_classes.apps.TwoCMSAppClassesConfig'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_without_cms_app_class.apps.WithoutCMSAppClassConfig'
1 change: 1 addition & 0 deletions cms/test_utils/project/app_without_cms_file/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'cms.test_utils.project.app_without_cms_file.apps.WithoutCMSFileConfig'
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def get_vary_cache_on(self, request, instance, placeholder):

def render(self, context, instance, placeholder):
request = context.get('request')
country_code = request.headers.get('country-code') or "any"
country_code = request.headers.get('Country-Code') or "any"
context['now'] = country_code
return context

Expand Down
3 changes: 2 additions & 1 deletion cms/test_utils/testcases.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist
from django.forms.models import model_to_dict
from django.http import HttpResponse
from django.template import engines
from django.template.context import Context
from django.test import testcases
Expand Down Expand Up @@ -451,7 +452,7 @@ def get_page_request(self, page, user, path=None, lang_code='en', disable=False,
if persist is not None:
request.GET[get_cms_setting('CMS_TOOLBAR_URL__PERSIST')] = persist
request.current_page = page
mid = ToolbarMiddleware()
mid = ToolbarMiddleware(lambda req: HttpResponse(""))
mid.process_request(request)
if hasattr(request, 'toolbar'):
request.toolbar.populate()
Expand Down
10 changes: 5 additions & 5 deletions cms/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,21 +760,21 @@ def test_smart_link_pages(self):
self.assertEqual(403, self.client.get(page_url).status_code)

self.assertEqual(200,
self.client.get(page_url, headers={"x-requested-with": 'XMLHttpRequest'}).status_code
self.client.get(page_url, HTTP_X_REQUESTED_WITH='XMLHttpRequest').status_code
)

# Test that the query param is working as expected.
self.assertEqual(1, len(json.loads(self.client.get(page_url, {'q':'main_title'},
headers={"x-requested-with": 'XMLHttpRequest'}).content.decode("utf-8"))))
HTTP_X_REQUESTED_WITH='XMLHttpRequest').content.decode("utf-8"))))

self.assertEqual(1, len(json.loads(self.client.get(page_url, {'q':'menu_title'},
headers={"x-requested-with": 'XMLHttpRequest'}).content.decode("utf-8"))))
HTTP_X_REQUESTED_WITH='XMLHttpRequest').content.decode("utf-8"))))

self.assertEqual(1, len(json.loads(self.client.get(page_url, {'q':'overwritten_url'},
headers={"x-requested-with": 'XMLHttpRequest'}).content.decode("utf-8"))))
HTTP_X_REQUESTED_WITH='XMLHttpRequest').content.decode("utf-8"))))

self.assertEqual(1, len(json.loads(self.client.get(page_url, {'q':'page_title'},
headers={"x-requested-with": 'XMLHttpRequest'}).content.decode("utf-8"))))
HTTP_X_REQUESTED_WITH='XMLHttpRequest').content.decode("utf-8"))))


class AdminPageEditContentSizeTests(AdminTestsBase):
Expand Down
3 changes: 2 additions & 1 deletion cms/tests/test_apphooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from cms.test_utils.testcases import CMSTestCase
from cms.tests.test_menu_utils import DumbPageLanguageUrl
from cms.toolbar.toolbar import CMSToolbar
from cms.utils.compat import DJANGO_3
from menus.menu_pool import menu_pool
from menus.utils import DefaultLanguageChanger

Expand Down Expand Up @@ -284,7 +285,7 @@ def test_apphook_permissions_preserves_view_name(self):
view_names = (
('sample-settings', 'sample_view'),
('sample-class-view', 'ClassView'),
('sample-class-based-view', 'ClassBasedView'),
('sample-class-based-view', 'ClassBasedView' if DJANGO_3 else 'view'),
)

with force_language("en"):
Expand Down
102 changes: 0 additions & 102 deletions cms/tests/test_docs.py

This file was deleted.

10 changes: 6 additions & 4 deletions cms/tests/test_i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@

from cms import api
from cms.test_utils.testcases import CMSTestCase
from cms.utils import i18n, get_language_from_request
from cms.utils import get_language_from_request, i18n
from cms.utils.compat import DJANGO_2_2

from cms.utils.compat import DJANGO_3_0, DJANGO_3_1, DJANGO_3_2
if DJANGO_2_2:
from django.utils.translation import LANGUAGE_SESSION_KEY


@override_settings(
Expand Down Expand Up @@ -361,7 +363,7 @@ def test_session_language(self):

# ugly and long set of session
session = self.client.session
if DJANGO_3_0 or DJANGO_3_1 or DJANGO_3_2:
if not DJANGO_2_2:
self.client.cookies[settings.LANGUAGE_COOKIE_NAME] = 'fr'
else:
session[LANGUAGE_SESSION_KEY] = 'fr'
Expand All @@ -370,7 +372,7 @@ def test_session_language(self):
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, '/fr/')
self.client.get('/en/')
if DJANGO_3_0 or DJANGO_3_1 or DJANGO_3_2:
if not DJANGO_2_2:
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, 'en')
else:
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], 'en')
Expand Down
4 changes: 2 additions & 2 deletions cms/tests/test_page_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.contrib.sites.models import Site
from django.core.cache import cache
from django.forms.models import model_to_dict
from django.http import HttpRequest
from django.http import HttpRequest, HttpResponse
from django.test.html import HTMLParseError, Parser
from django.test.utils import override_settings
from django.urls import clear_url_caches
Expand Down Expand Up @@ -1286,7 +1286,7 @@ def test_form_url_page_change(self):
content = self.get_page_title_obj(page, 'en')
form_url = self.get_page_change_uri('en', page)
# Middleware is needed to correctly setup the environment for the admin
middleware = CurrentUserMiddleware()
middleware = CurrentUserMiddleware(lambda req: HttpResponse(""))
request = self.get_request()
middleware.process_request(request)
response = content_admin.change_view(
Expand Down
3 changes: 2 additions & 1 deletion cms/tests/test_templatetags.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.contrib.sites.models import Site
from django.core import mail
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse
from django.test import RequestFactory
from django.test.utils import override_settings
from django.utils.encoding import force_str
Expand Down Expand Up @@ -181,7 +182,7 @@ def test_get_page_by_pk_arg_edit_mode(self):
user = self._create_user("admin", True, True)
request.current_page = control
request.user = user
middleware = ToolbarMiddleware()
middleware = ToolbarMiddleware(lambda req: HttpResponse(""))
middleware.process_request(request)
page = _get_page_by_untyped_arg(control.pk, request, 1)
self.assertEqual(page, control)
Expand Down
8 changes: 2 additions & 6 deletions cms/utils/compat/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
from platform import python_version
from django import get_version


try:
from packaging.version import Version
except ModuleNotFoundError:
from distutils.version import LooseVersion as Version
from django import get_version
from packaging.version import Version


DJANGO_VERSION = get_version()
Expand Down
2 changes: 2 additions & 0 deletions cms/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def details(request, slug):
user_languages = get_public_languages(site_id=site.pk)

request_language = get_language_from_request(request, check_path=True)
if not request_language:
request_language = get_default_language_for_site(get_current_site().pk)

if not page.is_home and request_language not in user_languages:
# The homepage is treated differently because
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ MarkupSafe==0.23
Pygments==2.0.2
sphinx
sphinxcontrib-spelling
pyenchant==3.0.1
pyenchant==3.2.2
sphinx-autobuild
divio-docs-theme
datetime
Expand Down
Loading
Loading