1
0
mirror of https://github.com/django/django.git synced 2025-03-03 13:34:26 +00:00

Refs #34380 -- Added FORMS_URLFIELD_ASSUME_HTTPS transitional setting.

This allows early adoption of the new default "https".
This commit is contained in:
Mariusz Felisiak 2023-11-28 20:04:21 +01:00 committed by GitHub
parent 5f9e5c1b0d
commit a4931cd75a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 113 additions and 12 deletions

View File

@ -16,12 +16,18 @@ from pathlib import Path
import django
from django.conf import global_settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.functional import LazyObject, empty
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
DEFAULT_STORAGE_ALIAS = "default"
STATICFILES_STORAGE_ALIAS = "staticfiles"
# RemovedInDjango60Warning.
FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG = (
"The FORMS_URLFIELD_ASSUME_HTTPS transitional setting is deprecated."
)
class SettingsReference(str):
"""
@ -180,6 +186,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.
@ -224,6 +236,11 @@ class UserSettingsHolder:
def __setattr__(self, name, value):
self._deleted.discard(name)
if name == "FORMS_URLFIELD_ASSUME_HTTPS":
warnings.warn(
FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG,
RemovedInDjango60Warning,
)
super().__setattr__(name, value)
def __delattr__(self, name):

View File

@ -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"

View File

@ -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

View File

@ -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.
See the :ref:`Django 5.1 release notes <deprecated-features-5.1>` for more
details on these changes.

View File

@ -1155,7 +1155,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``
-------------

View File

@ -1675,6 +1675,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``
@ -3635,6 +3649,7 @@ File uploads
Forms
-----
* :setting:`FORM_RENDERER`
* :setting:`FORMS_URLFIELD_ASSUME_HTTPS`
Globalization (``i18n``/``l10n``)
---------------------------------

View File

@ -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.

View File

@ -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)

View File

@ -2930,7 +2930,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):
@ -2939,6 +2940,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