1
0
mirror of https://github.com/django/django.git synced 2025-05-02 21:24:39 +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 import django
from django.conf import global_settings from django.conf import global_settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.functional import LazyObject, empty from django.utils.functional import LazyObject, empty
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
DEFAULT_STORAGE_ALIAS = "default" DEFAULT_STORAGE_ALIAS = "default"
STATICFILES_STORAGE_ALIAS = "staticfiles" STATICFILES_STORAGE_ALIAS = "staticfiles"
# RemovedInDjango60Warning.
FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG = (
"The FORMS_URLFIELD_ASSUME_HTTPS transitional setting is deprecated."
)
class SettingsReference(str): class SettingsReference(str):
""" """
@ -180,6 +186,12 @@ class Settings:
setattr(self, setting, setting_value) setattr(self, setting, setting_value)
self._explicit_settings.add(setting) 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: if hasattr(time, "tzset") and self.TIME_ZONE:
# When we can, attempt to validate the timezone. If we can't find # When we can, attempt to validate the timezone. If we can't find
# this file, no check happens and it's harmless. # this file, no check happens and it's harmless.
@ -224,6 +236,11 @@ class UserSettingsHolder:
def __setattr__(self, name, value): def __setattr__(self, name, value):
self._deleted.discard(name) self._deleted.discard(name)
if name == "FORMS_URLFIELD_ASSUME_HTTPS":
warnings.warn(
FORMS_URLFIELD_ASSUME_HTTPS_DEPRECATED_MSG,
RemovedInDjango60Warning,
)
super().__setattr__(name, value) super().__setattr__(name, value)
def __delattr__(self, name): def __delattr__(self, name):

View File

@ -216,6 +216,11 @@ TEMPLATES = []
# Default form rendering class. # Default form rendering class.
FORM_RENDERER = "django.forms.renderers.DjangoTemplates" 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 # Default email address to use for various automated correspondence from
# the site managers. # the site managers.
DEFAULT_FROM_EMAIL = "webmaster@localhost" DEFAULT_FROM_EMAIL = "webmaster@localhost"

View File

@ -15,6 +15,7 @@ from decimal import Decimal, DecimalException
from io import BytesIO from io import BytesIO
from urllib.parse import urlsplit, urlunsplit from urllib.parse import urlsplit, urlunsplit
from django.conf import settings
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms.boundfield import BoundField from django.forms.boundfield import BoundField
@ -762,14 +763,19 @@ class URLField(CharField):
def __init__(self, *, assume_scheme=None, **kwargs): def __init__(self, *, assume_scheme=None, **kwargs):
if assume_scheme is None: if assume_scheme is None:
warnings.warn( if settings.FORMS_URLFIELD_ASSUME_HTTPS:
"The default scheme will be changed from 'http' to 'https' in Django " assume_scheme = "https"
"6.0. Pass the forms.URLField.assume_scheme argument to silence this " else:
"warning.", warnings.warn(
RemovedInDjango60Warning, "The default scheme will be changed from 'http' to 'https' in "
stacklevel=2, "Django 6.0. Pass the forms.URLField.assume_scheme argument to "
) "silence this warning, or set the FORMS_URLFIELD_ASSUME_HTTPS "
assume_scheme = "http" "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: # RemovedInDjango60Warning: When the deprecation ends, replace with:
# self.assume_scheme = assume_scheme or "https" # self.assume_scheme = assume_scheme or "https"
self.assume_scheme = assume_scheme self.assume_scheme = assume_scheme

View File

@ -53,6 +53,8 @@ details on these changes.
* ``get_prefetcher()`` and ``prefetch_related_objects()`` will no longer * ``get_prefetcher()`` and ``prefetch_related_objects()`` will no longer
fallback to ``get_prefetch_queryset()``. 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 See the :ref:`Django 5.1 release notes <deprecated-features-5.1>` for more
details on these changes. 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 .. deprecated:: 5.0
The default value for ``assume_scheme`` will change from ``"http"`` to 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`` ``UUIDField``
------------- -------------

View File

@ -1675,6 +1675,20 @@ renderers are:
* ``'``:class:`django.forms.renderers.Jinja2`\ ``'`` * ``'``:class:`django.forms.renderers.Jinja2`\ ``'``
* ``'``:class:`django.forms.renderers.TemplatesSetting`\ ``'`` * ``'``: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 .. setting:: FORMAT_MODULE_PATH
``FORMAT_MODULE_PATH`` ``FORMAT_MODULE_PATH``
@ -3635,6 +3649,7 @@ File uploads
Forms Forms
----- -----
* :setting:`FORM_RENDERER` * :setting:`FORM_RENDERER`
* :setting:`FORMS_URLFIELD_ASSUME_HTTPS`
Globalization (``i18n``/``l10n``) Globalization (``i18n``/``l10n``)
--------------------------------- ---------------------------------

View File

@ -612,7 +612,11 @@ Miscellaneous
* The ``ForeignObject.get_reverse_joining_columns()`` method is deprecated. * The ``ForeignObject.get_reverse_joining_columns()`` method is deprecated.
* The default scheme for ``forms.URLField`` will change from ``"http"`` to * 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 * Support for calling ``format_html()`` without passing args or kwargs will be
removed. 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.core.exceptions import ValidationError
from django.forms import URLField from django.forms import URLField
from django.test import SimpleTestCase, ignore_warnings from django.test import SimpleTestCase, ignore_warnings
@ -155,8 +159,41 @@ class URLFieldAssumeSchemeDeprecationTest(FormFieldAssertionsMixin, SimpleTestCa
def test_urlfield_raises_warning(self): def test_urlfield_raises_warning(self):
msg = ( msg = (
"The default scheme will be changed from 'http' to 'https' in Django 6.0. " "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): with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
f = URLField() f = URLField()
self.assertEqual(f.clean("example.com"), "http://example.com") 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 = ( msg = (
"The default scheme will be changed from 'http' to 'https' in Django " "The default scheme will be changed from 'http' to 'https' in Django "
"6.0. Pass the forms.URLField.assume_scheme argument to silence this " "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): with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
@ -2939,6 +2940,18 @@ class ModelOtherFieldTests(SimpleTestCase):
model = Homepage model = Homepage
fields = "__all__" 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): def test_modelform_non_editable_field(self):
""" """
When explicitly including a non-editable field in a ModelForm, the When explicitly including a non-editable field in a ModelForm, the