summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2023-11-28 20:04:21 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-11-28 20:08:10 +0100
commit92af3d4d235448446e53e982275315bedcc4c204 (patch)
treeb0859a9cdebea2a3c6c242a55dfb333ba5cba4b4
parent432bfa26151f1330dddf1635358a3b60a5947b9f (diff)
[5.0.x] Refs #34380 -- Added FORMS_URLFIELD_ASSUME_HTTPS transitional setting.
This allows early adoption of the new default "https". Backport of a4931cd75a1780923b02e43475ba5447df3adb31 from main.
-rw-r--r--django/conf/__init__.py18
-rw-r--r--django/conf/global_settings.py5
-rw-r--r--django/forms/fields.py22
-rw-r--r--docs/internals/deprecation.txt2
-rw-r--r--docs/ref/forms/fields.txt4
-rw-r--r--docs/ref/settings.txt15
-rw-r--r--docs/releases/5.0.txt6
-rw-r--r--tests/forms_tests/field_tests/test_urlfield.py39
-rw-r--r--tests/model_forms/tests.py15
9 files changed, 113 insertions, 13 deletions
diff --git a/django/conf/__init__.py b/django/conf/__init__.py
index 22f1eaba06..8d5fdd5b54 100644
--- a/django/conf/__init__.py
+++ b/django/conf/__init__.py
@@ -16,7 +16,7 @@ from pathlib import Path
import django
from django.conf import global_settings
from django.core.exceptions import ImproperlyConfigured
-from django.utils.deprecation import RemovedInDjango51Warning
+from django.utils.deprecation import RemovedInDjango51Warning, RemovedInDjango60Warning
from django.utils.functional import LazyObject, empty
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
@@ -31,6 +31,11 @@ STATICFILES_STORAGE_DEPRECATED_MSG = (
"The STATICFILES_STORAGE setting is deprecated. Use STORAGES instead."
)
+# RemovedInDjango60Warning.
+FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG = (
+ "The FORMS_URLFIELD_ASSUME_HTTPS transitional setting is deprecated."
+)
+
class SettingsReference(str):
"""
@@ -205,6 +210,12 @@ class Settings:
setattr(self, setting, setting_value)
self._explicit_settings.add(setting)
+ if self.is_overridden("FORMS_URLFIELD_ASSUME_HTTPS"):
+ warnings.warn(
+ FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG,
+ RemovedInDjango60Warning,
+ )
+
if hasattr(time, "tzset") and self.TIME_ZONE:
# When we can, attempt to validate the timezone. If we can't find
# this file, no check happens and it's harmless.
@@ -293,6 +304,11 @@ class UserSettingsHolder:
"BACKEND": self.STATICFILES_STORAGE
}
warnings.warn(STATICFILES_STORAGE_DEPRECATED_MSG, RemovedInDjango51Warning)
+ if name == "FORMS_URLFIELD_ASSUME_HTTPS":
+ warnings.warn(
+ FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG,
+ RemovedInDjango60Warning,
+ )
super().__setattr__(name, value)
# RemovedInDjango51Warning.
if name == "STORAGES":
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index 01f9b57fb2..18253b03e4 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -216,6 +216,11 @@ TEMPLATES = []
# Default form rendering class.
FORM_RENDERER = "django.forms.renderers.DjangoTemplates"
+# RemovedInDjango60Warning: It's a transitional setting helpful in early
+# adoption of "https" as the new default value of forms.URLField.assume_scheme.
+# Set to True to assume "https" during the Django 5.x release cycle.
+FORMS_URLFIELD_ASSUME_HTTPS = False
+
# Default email address to use for various automated correspondence from
# the site managers.
DEFAULT_FROM_EMAIL = "webmaster@localhost"
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 3a0510ffc9..f00d567a3a 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -15,6 +15,7 @@ from decimal import Decimal, DecimalException
from io import BytesIO
from urllib.parse import urlsplit, urlunsplit
+from django.conf import settings
from django.core import validators
from django.core.exceptions import ValidationError
from django.forms.boundfield import BoundField
@@ -762,14 +763,19 @@ class URLField(CharField):
def __init__(self, *, assume_scheme=None, **kwargs):
if assume_scheme is None:
- warnings.warn(
- "The default scheme will be changed from 'http' to 'https' in Django "
- "6.0. Pass the forms.URLField.assume_scheme argument to silence this "
- "warning.",
- RemovedInDjango60Warning,
- stacklevel=2,
- )
- assume_scheme = "http"
+ if settings.FORMS_URLFIELD_ASSUME_HTTPS:
+ assume_scheme = "https"
+ else:
+ warnings.warn(
+ "The default scheme will be changed from 'http' to 'https' in "
+ "Django 6.0. Pass the forms.URLField.assume_scheme argument to "
+ "silence this warning, or set the FORMS_URLFIELD_ASSUME_HTTPS "
+ "transitional setting to True to opt into using 'https' as the new "
+ "default scheme.",
+ RemovedInDjango60Warning,
+ stacklevel=2,
+ )
+ assume_scheme = "http"
# RemovedInDjango60Warning: When the deprecation ends, replace with:
# self.assume_scheme = assume_scheme or "https"
self.assume_scheme = assume_scheme
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 632c1e219d..38ce061db8 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -53,6 +53,8 @@ details on these changes.
* ``get_prefetcher()`` and ``prefetch_related_objects()`` will no longer
fallback to ``get_prefetch_queryset()``.
+* The ``FORMS_URLFIELD_ASSUME_HTTPS`` transitional setting will be removed.
+
.. _deprecation-removed-in-5.1:
5.1
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
index 6eca7234fc..9ccd69823a 100644
--- a/docs/ref/forms/fields.txt
+++ b/docs/ref/forms/fields.txt
@@ -1154,7 +1154,9 @@ For each field, we describe the default widget used if you don't specify
.. deprecated:: 5.0
The default value for ``assume_scheme`` will change from ``"http"`` to
- ``"https"`` in Django 6.0.
+ ``"https"`` in Django 6.0. Set :setting:`FORMS_URLFIELD_ASSUME_HTTPS`
+ transitional setting to ``True`` to opt into using ``"https"`` during
+ the Django 5.x release cycle.
``UUIDField``
-------------
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index f81314f1ff..28d72e356e 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -1693,6 +1693,20 @@ renderers are:
* ``'``:class:`django.forms.renderers.Jinja2`\ ``'``
* ``'``:class:`django.forms.renderers.TemplatesSetting`\ ``'``
+.. setting:: FORMS_URLFIELD_ASSUME_HTTPS
+
+``FORMS_URLFIELD_ASSUME_HTTPS``
+-------------------------------
+
+.. versionadded:: 5.0
+.. deprecated:: 5.0
+
+Default: ``False``
+
+Set this transitional setting to ``True`` to opt into using ``"https"`` as the
+new default value of :attr:`URLField.assume_scheme
+<django.forms.URLField.assume_scheme>` during the Django 5.x release cycle.
+
.. setting:: FORMAT_MODULE_PATH
``FORMAT_MODULE_PATH``
@@ -3677,6 +3691,7 @@ File uploads
Forms
-----
* :setting:`FORM_RENDERER`
+* :setting:`FORMS_URLFIELD_ASSUME_HTTPS`
Globalization (``i18n``/``l10n``)
---------------------------------
diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt
index b74a0f00c7..ebddec38e6 100644
--- a/docs/releases/5.0.txt
+++ b/docs/releases/5.0.txt
@@ -612,7 +612,11 @@ Miscellaneous
* The ``ForeignObject.get_reverse_joining_columns()`` method is deprecated.
* The default scheme for ``forms.URLField`` will change from ``"http"`` to
- ``"https"`` in Django 6.0.
+ ``"https"`` in Django 6.0. Set :setting:`FORMS_URLFIELD_ASSUME_HTTPS`
+ transitional setting to ``True`` to opt into assuming ``"https"`` during the
+ Django 5.x release cycle.
+
+* ``FORMS_URLFIELD_ASSUME_HTTPS`` transitional setting is deprecated.
* Support for calling ``format_html()`` without passing args or kwargs will be
removed.
diff --git a/tests/forms_tests/field_tests/test_urlfield.py b/tests/forms_tests/field_tests/test_urlfield.py
index 058a2992ed..d8fd5532e0 100644
--- a/tests/forms_tests/field_tests/test_urlfield.py
+++ b/tests/forms_tests/field_tests/test_urlfield.py
@@ -1,3 +1,7 @@
+import sys
+from types import ModuleType
+
+from django.conf import FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG, Settings, settings
from django.core.exceptions import ValidationError
from django.forms import URLField
from django.test import SimpleTestCase, ignore_warnings
@@ -155,8 +159,41 @@ class URLFieldAssumeSchemeDeprecationTest(FormFieldAssertionsMixin, SimpleTestCa
def test_urlfield_raises_warning(self):
msg = (
"The default scheme will be changed from 'http' to 'https' in Django 6.0. "
- "Pass the forms.URLField.assume_scheme argument to silence this warning."
+ "Pass the forms.URLField.assume_scheme argument to silence this warning, "
+ "or set the FORMS_URLFIELD_ASSUME_HTTPS transitional setting to True to "
+ "opt into using 'https' as the new default scheme."
)
with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
f = URLField()
self.assertEqual(f.clean("example.com"), "http://example.com")
+
+ @ignore_warnings(category=RemovedInDjango60Warning)
+ def test_urlfield_forms_urlfield_assume_https(self):
+ with self.settings(FORMS_URLFIELD_ASSUME_HTTPS=True):
+ f = URLField()
+ self.assertEqual(f.clean("example.com"), "https://example.com")
+ f = URLField(assume_scheme="http")
+ self.assertEqual(f.clean("example.com"), "http://example.com")
+
+ def test_override_forms_urlfield_assume_https_setting_warning(self):
+ msg = FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG
+ with self.assertRaisesMessage(RemovedInDjango60Warning, msg):
+ # Changing FORMS_URLFIELD_ASSUME_HTTPS via self.settings() raises a
+ # deprecation warning.
+ with self.settings(FORMS_URLFIELD_ASSUME_HTTPS=True):
+ pass
+
+ def test_settings_init_forms_urlfield_assume_https_warning(self):
+ settings_module = ModuleType("fake_settings_module")
+ settings_module.FORMS_URLFIELD_ASSUME_HTTPS = True
+ sys.modules["fake_settings_module"] = settings_module
+ msg = FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG
+ try:
+ with self.assertRaisesMessage(RemovedInDjango60Warning, msg):
+ Settings("fake_settings_module")
+ finally:
+ del sys.modules["fake_settings_module"]
+
+ def test_access_forms_urlfield_assume_https(self):
+ # Warning is not raised on access.
+ self.assertEqual(settings.FORMS_URLFIELD_ASSUME_HTTPS, False)
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index 43bb770f7e..d138fca8fb 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -2929,7 +2929,8 @@ class ModelOtherFieldTests(SimpleTestCase):
msg = (
"The default scheme will be changed from 'http' to 'https' in Django "
"6.0. Pass the forms.URLField.assume_scheme argument to silence this "
- "warning."
+ "warning, or set the FORMS_URLFIELD_ASSUME_HTTPS transitional setting to "
+ "True to opt into using 'https' as the new default scheme."
)
with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
@@ -2938,6 +2939,18 @@ class ModelOtherFieldTests(SimpleTestCase):
model = Homepage
fields = "__all__"
+ def test_url_modelform_assume_scheme_early_adopt_https(self):
+ msg = "The FORMS_URLFIELD_ASSUME_HTTPS transitional setting is deprecated."
+ with (
+ self.assertWarnsMessage(RemovedInDjango60Warning, msg),
+ self.settings(FORMS_URLFIELD_ASSUME_HTTPS=True),
+ ):
+
+ class HomepageForm(forms.ModelForm):
+ class Meta:
+ model = Homepage
+ fields = "__all__"
+
def test_modelform_non_editable_field(self):
"""
When explicitly including a non-editable field in a ModelForm, the