mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	[5.0.x] Refs #34380 -- Added FORMS_URLFIELD_ASSUME_HTTPS transitional setting.
This allows early adoption of the new default "https".
Backport of a4931cd75a from main.
			
			
This commit is contained in:
		| @@ -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": | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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,10 +763,15 @@ class URLField(CharField): | ||||
|  | ||||
|     def __init__(self, *, assume_scheme=None, **kwargs): | ||||
|         if assume_scheme is None: | ||||
|             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.", | ||||
|                     "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, | ||||
|                 ) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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`` | ||||
| ------------- | ||||
|   | ||||
| @@ -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``) | ||||
| --------------------------------- | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user