From 9a3f86e96009c1137b286f6d579b9d812a0dee69 Mon Sep 17 00:00:00 2001 From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:39:58 +0100 Subject: [PATCH] Refs #34380 -- Changed the URLField default scheme to https and removed FORMS_URLFIELD_ASSUME_HTTPS per deprecation timeline. --- django/conf/__init__.py | 17 ------ django/conf/global_settings.py | 5 -- django/forms/fields.py | 21 +------ docs/ref/forms/fields.txt | 7 --- docs/ref/settings.txt | 14 ----- docs/releases/5.0.txt | 6 +- docs/releases/6.0.txt | 5 ++ tests/admin_views/tests.py | 7 --- tests/admin_widgets/tests.py | 7 +-- .../forms_tests/field_tests/test_urlfield.py | 61 +------------------ .../forms_tests/tests/test_error_messages.py | 8 +-- tests/generic_inline_admin/tests.py | 15 +---- tests/model_forms/tests.py | 43 +------------ 13 files changed, 19 insertions(+), 197 deletions(-) diff --git a/django/conf/__init__.py b/django/conf/__init__.py index 5568d7cc83..6b5f044e34 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -16,18 +16,12 @@ 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): """ @@ -186,12 +180,6 @@ 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. @@ -236,11 +224,6 @@ 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): diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index f4535acb09..536bbb7c45 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -218,11 +218,6 @@ 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 4bd9c352f2..04aa2039fd 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -10,12 +10,10 @@ import operator import os import re import uuid -import warnings 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 @@ -44,7 +42,6 @@ from django.forms.widgets import ( from django.utils import formats from django.utils.choices import normalize_choices from django.utils.dateparse import parse_datetime, parse_duration -from django.utils.deprecation import RemovedInDjango60Warning from django.utils.duration import duration_string from django.utils.ipv6 import MAX_IPV6_ADDRESS_LENGTH, clean_ipv6_address from django.utils.regex_helper import _lazy_re_compile @@ -777,23 +774,7 @@ class URLField(CharField): default_validators = [validators.URLValidator()] 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, 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 + self.assume_scheme = assume_scheme or "https" super().__init__(strip=True, **kwargs) def to_python(self, value): diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 91faea12f7..df8d36e365 100644 --- a/docs/ref/forms/fields.txt +++ b/docs/ref/forms/fields.txt @@ -1146,13 +1146,6 @@ For each field, we describe the default widget used if you don't specify provided value is ``"example.com"``, the normalized value will be ``"https://example.com"``. - .. deprecated:: 5.0 - - The default value for ``assume_scheme`` will change from ``"http"`` to - ``"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 e3a0f6d32a..9bd5aedbed 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -1684,19 +1684,6 @@ renderers are: * ``'``:class:`django.forms.renderers.Jinja2`\ ``'`` * ``'``:class:`django.forms.renderers.TemplatesSetting`\ ``'`` -.. setting:: FORMS_URLFIELD_ASSUME_HTTPS - -``FORMS_URLFIELD_ASSUME_HTTPS`` -------------------------------- - -.. 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 -` during the Django 5.x release cycle. - .. setting:: FORMAT_MODULE_PATH ``FORMAT_MODULE_PATH`` @@ -3664,7 +3651,6 @@ 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 303ee88078..1cc5695d5a 100644 --- a/docs/releases/5.0.txt +++ b/docs/releases/5.0.txt @@ -622,9 +622,9 @@ 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. Set :setting:`FORMS_URLFIELD_ASSUME_HTTPS` - transitional setting to ``True`` to opt into assuming ``"https"`` during the - Django 5.x release cycle. + ``"https"`` in Django 6.0. Set ``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. diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt index d8db925fd1..7ae24a422f 100644 --- a/docs/releases/6.0.txt +++ b/docs/releases/6.0.txt @@ -268,6 +268,11 @@ to remove usage of these features. * Support for calling ``format_html()`` without passing args or kwargs is removed. +* The default scheme for ``forms.URLField`` changed from ``"http"`` to + ``"https"``. + +* The ``FORMS_URLFIELD_ASSUME_HTTPS`` transitional setting is removed. + See :ref:`deprecated-features-5.1` for details on these changes, including how to remove usage of these features. diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 8e2c55804b..7642a186c0 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -29,7 +29,6 @@ from django.template.response import TemplateResponse from django.test import ( RequestFactory, TestCase, - ignore_warnings, modify_settings, override_settings, skipUnlessDBFeature, @@ -39,7 +38,6 @@ from django.test.utils import override_script_prefix from django.urls import NoReverseMatch, resolve, reverse from django.utils import formats, translation from django.utils.cache import get_max_age -from django.utils.deprecation import RemovedInDjango60Warning from django.utils.encoding import iri_to_uri from django.utils.html import escape from django.utils.http import urlencode @@ -6873,7 +6871,6 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): def setUp(self): self.client.force_login(self.superuser) - @ignore_warnings(category=RemovedInDjango60Warning) def test_readonly_get(self): response = self.client.get(reverse("admin:admin_views_post_add")) self.assertNotContains(response, 'name="posted"') @@ -6934,7 +6931,6 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): ) self.assertContains(response, "%d amount of cool" % p.pk) - @ignore_warnings(category=RemovedInDjango60Warning) def test_readonly_text_field(self): p = Post.objects.create( title="Readonly test", @@ -6954,7 +6950,6 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): # Checking readonly field in inline. self.assertContains(response, "test
link") - @ignore_warnings(category=RemovedInDjango60Warning) def test_readonly_post(self): data = { "title": "Django Got Readonly Fields", @@ -7100,7 +7095,6 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): response = self.client.get(reverse("admin:admin_views_square_add")) self.assertContains(response, '
-
') - @ignore_warnings(category=RemovedInDjango60Warning) def test_readonly_field_overrides(self): """ Regression test for #22087 - ModelForm Meta overrides are ignored by @@ -7558,7 +7552,6 @@ class CSSTest(TestCase): def setUp(self): self.client.force_login(self.superuser) - @ignore_warnings(category=RemovedInDjango60Warning) def test_field_prefix_css_classes(self): """ Fields have a CSS class name with a 'field-' prefix. diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index 0cf1324623..fb296c8655 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -22,12 +22,11 @@ from django.db.models import ( ManyToManyField, UUIDField, ) -from django.test import SimpleTestCase, TestCase, ignore_warnings, override_settings +from django.test import SimpleTestCase, TestCase, override_settings from django.test.selenium import screenshot_cases from django.test.utils import requires_tz_support from django.urls import reverse from django.utils import translation -from django.utils.deprecation import RemovedInDjango60Warning from .models import ( Advisor, @@ -109,7 +108,6 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase): def test_TextField(self): self.assertFormfield(Event, "description", widgets.AdminTextareaWidget) - @ignore_warnings(category=RemovedInDjango60Warning) def test_URLField(self): self.assertFormfield(Event, "link", widgets.AdminURLFieldWidget) @@ -324,7 +322,6 @@ class AdminForeignKeyRawIdWidget(TestDataMixin, TestCase): def setUp(self): self.client.force_login(self.superuser) - @ignore_warnings(category=RemovedInDjango60Warning) def test_nonexistent_target_id(self): band = Band.objects.create(name="Bogey Blues") pk = band.pk @@ -340,7 +337,6 @@ class AdminForeignKeyRawIdWidget(TestDataMixin, TestCase): "Select a valid choice. That choice is not one of the available choices.", ) - @ignore_warnings(category=RemovedInDjango60Warning) def test_invalid_target_id(self): for test_str in ("Iñtërnâtiônàlizætiøn", "1234'", -1234): # This should result in an error message, not a server exception. @@ -1738,7 +1734,6 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase): self.assertCountSeleniumElements("#id_students_to > option", 2) -@ignore_warnings(category=RemovedInDjango60Warning) class AdminRawIdWidgetSeleniumTests(AdminWidgetSeleniumTestCase): def setUp(self): super().setUp() diff --git a/tests/forms_tests/field_tests/test_urlfield.py b/tests/forms_tests/field_tests/test_urlfield.py index 54bc7c5e46..f7d318fdc9 100644 --- a/tests/forms_tests/field_tests/test_urlfield.py +++ b/tests/forms_tests/field_tests/test_urlfield.py @@ -1,16 +1,10 @@ -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 -from django.utils.deprecation import RemovedInDjango60Warning +from django.test import SimpleTestCase from . import FormFieldAssertionsMixin -@ignore_warnings(category=RemovedInDjango60Warning) class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_urlfield_widget(self): f = URLField() @@ -32,9 +26,7 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): f.clean("http://abcdefghijklmnopqrstuvwxyz.com") def test_urlfield_clean(self): - # RemovedInDjango60Warning: When the deprecation ends, remove the - # assume_scheme argument. - f = URLField(required=False, assume_scheme="https") + f = URLField(required=False) tests = [ ("http://localhost", "http://localhost"), ("http://example.com", "http://example.com"), @@ -146,55 +138,8 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_urlfield_assume_scheme(self): f = URLField() - # RemovedInDjango60Warning: When the deprecation ends, replace with: - # "https://example.com" - self.assertEqual(f.clean("example.com"), "http://example.com") + self.assertEqual(f.clean("example.com"), "https://example.com") f = URLField(assume_scheme="http") self.assertEqual(f.clean("example.com"), "http://example.com") f = URLField(assume_scheme="https") self.assertEqual(f.clean("example.com"), "https://example.com") - - -class URLFieldAssumeSchemeDeprecationTest(FormFieldAssertionsMixin, SimpleTestCase): - 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, " - "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) as ctx: - f = URLField() - self.assertEqual(f.clean("example.com"), "http://example.com") - self.assertEqual(ctx.filename, __file__) - - @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/forms_tests/tests/test_error_messages.py b/tests/forms_tests/tests/test_error_messages.py index f4f5700107..e6bfa35dfb 100644 --- a/tests/forms_tests/tests/test_error_messages.py +++ b/tests/forms_tests/tests/test_error_messages.py @@ -23,8 +23,7 @@ from django.forms import ( utils, ) from django.template import Context, Template -from django.test import SimpleTestCase, TestCase, ignore_warnings -from django.utils.deprecation import RemovedInDjango60Warning +from django.test import SimpleTestCase, TestCase from django.utils.safestring import mark_safe from ..models import ChoiceModel @@ -168,12 +167,11 @@ class FormsErrorMessagesTestCase(SimpleTestCase, AssertFormErrorsMixin): "invalid": "INVALID", "max_length": '"%(value)s" has more than %(limit_value)d characters.', } - with ignore_warnings(category=RemovedInDjango60Warning): - f = URLField(error_messages=e, max_length=17) + f = URLField(error_messages=e, max_length=17) self.assertFormErrors(["REQUIRED"], f.clean, "") self.assertFormErrors(["INVALID"], f.clean, "abc.c") self.assertFormErrors( - ['"http://djangoproject.com" has more than 17 characters.'], + ['"https://djangoproject.com" has more than 17 characters.'], f.clean, "djangoproject.com", ) diff --git a/tests/generic_inline_admin/tests.py b/tests/generic_inline_admin/tests.py index 13819725d6..dfc8f4f7cf 100644 --- a/tests/generic_inline_admin/tests.py +++ b/tests/generic_inline_admin/tests.py @@ -5,15 +5,8 @@ from django.contrib.contenttypes.admin import GenericTabularInline from django.contrib.contenttypes.models import ContentType from django.forms.formsets import DEFAULT_MAX_NUM from django.forms.models import ModelForm -from django.test import ( - RequestFactory, - SimpleTestCase, - TestCase, - ignore_warnings, - override_settings, -) +from django.test import RequestFactory, SimpleTestCase, TestCase, override_settings from django.urls import reverse -from django.utils.deprecation import RemovedInDjango60Warning from .admin import MediaInline, MediaPermanentInline from .admin import site as admin_site @@ -28,7 +21,6 @@ class TestDataMixin: ) -@ignore_warnings(category=RemovedInDjango60Warning) @override_settings(ROOT_URLCONF="generic_inline_admin.urls") class GenericAdminViewTest(TestDataMixin, TestCase): def setUp(self): @@ -103,7 +95,6 @@ class GenericAdminViewTest(TestDataMixin, TestCase): self.assertEqual(response.status_code, 302) # redirect somewhere -@ignore_warnings(category=RemovedInDjango60Warning) @override_settings(ROOT_URLCONF="generic_inline_admin.urls") class GenericInlineAdminParametersTest(TestDataMixin, TestCase): factory = RequestFactory() @@ -305,7 +296,6 @@ class GenericInlineAdminWithUniqueTogetherTest(TestDataMixin, TestCase): @override_settings(ROOT_URLCONF="generic_inline_admin.urls") class NoInlineDeletionTest(SimpleTestCase): - @ignore_warnings(category=RemovedInDjango60Warning) def test_no_deletion(self): inline = MediaPermanentInline(EpisodePermanent, admin_site) fake_request = object() @@ -331,7 +321,6 @@ class GenericInlineModelAdminTest(SimpleTestCase): def setUp(self): self.site = AdminSite() - @ignore_warnings(category=RemovedInDjango60Warning) def test_get_formset_kwargs(self): media_inline = MediaInline(Media, AdminSite()) @@ -371,7 +360,6 @@ class GenericInlineModelAdminTest(SimpleTestCase): ["keywords", "id", "DELETE"], ) - @ignore_warnings(category=RemovedInDjango60Warning) def test_custom_form_meta_exclude(self): """ The custom ModelForm's `Meta.exclude` is respected by @@ -415,7 +403,6 @@ class GenericInlineModelAdminTest(SimpleTestCase): ["description", "keywords", "id", "DELETE"], ) - @ignore_warnings(category=RemovedInDjango60Warning) def test_get_fieldsets(self): # get_fieldsets is called when figuring out form fields. # Refs #18681. diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index fd043d3d03..a432f6ce43 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -22,10 +22,9 @@ from django.forms.models import ( modelform_factory, ) from django.template import Context, Template -from django.test import SimpleTestCase, TestCase, ignore_warnings, skipUnlessDBFeature +from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature from django.test.utils import isolate_apps from django.utils.choices import BlankChoiceIterator -from django.utils.deprecation import RemovedInDjango60Warning from django.utils.version import PY314, PYPY from .models import ( @@ -374,7 +373,6 @@ class ModelFormBaseTest(TestCase): obj = form.save() self.assertEqual(obj.name, "") - @ignore_warnings(category=RemovedInDjango60Warning) def test_save_blank_null_unique_charfield_saves_null(self): form_class = modelform_factory( model=NullableUniqueCharFieldModel, fields="__all__" @@ -913,13 +911,6 @@ class ModelFormBaseTest(TestCase): self.assertEqual(m2.date_published, datetime.date(2010, 1, 1)) -# RemovedInDjango60Warning. -# It's a temporary workaround for the deprecation period. -class HttpsURLField(forms.URLField): - def __init__(self, **kwargs): - super().__init__(assume_scheme="https", **kwargs) - - class FieldOverridesByFormMetaForm(forms.ModelForm): class Meta: model = Category @@ -943,7 +934,7 @@ class FieldOverridesByFormMetaForm(forms.ModelForm): } } field_classes = { - "url": HttpsURLField, + "url": forms.URLField, } @@ -2918,7 +2909,6 @@ class ModelOtherFieldTests(SimpleTestCase): }, ) - @ignore_warnings(category=RemovedInDjango60Warning) def test_url_on_modelform(self): "Check basic URL field validation on model forms" @@ -2943,32 +2933,6 @@ class ModelOtherFieldTests(SimpleTestCase): ) self.assertTrue(HomepageForm({"url": "http://example.com/foo/bar"}).is_valid()) - def test_url_modelform_assume_scheme_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, 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): - - class HomepageForm(forms.ModelForm): - class Meta: - 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 @@ -2995,9 +2959,6 @@ class ModelOtherFieldTests(SimpleTestCase): """ class HomepageForm(forms.ModelForm): - # RemovedInDjango60Warning. - url = forms.URLField(assume_scheme="https") - class Meta: model = Homepage fields = "__all__"