diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 81b57f33aada..f5c393901254 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -122,6 +122,7 @@ class AdminRadioSelect(forms.RadioSelect): class AdminFileWidget(forms.ClearableFileInput): template_name = "admin/widgets/clearable_file_input.html" + use_fieldset = True def url_params_from_lookup_dict(lookups): diff --git a/django/db/backends/postgresql/compiler.py b/django/db/backends/postgresql/compiler.py index 48d0ccfd9d06..9d383b52e8cc 100644 --- a/django/db/backends/postgresql/compiler.py +++ b/django/db/backends/postgresql/compiler.py @@ -53,7 +53,9 @@ def assemble_as_sql(self, fields, value_rows): or any(any(hasattr(value, "as_sql") for value in row) for row in value_rows) ): return super().assemble_as_sql(fields, value_rows) - db_types = [field.db_type(self.connection) for field in fields] + # Manually remove parameters from `db_type` to ensure no data + # truncation takes place (e.g. varchar[] instead of varchar(50)[]). + db_types = [field.db_type(self.connection).split("(")[0] for field in fields] return InsertUnnest(["(%%s)::%s[]" % db_type for db_type in db_types]), [ list(map(list, zip(*value_rows))) ] diff --git a/django/forms/widgets.py b/django/forms/widgets.py index b77e57abce64..1bcfeba2886e 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -530,7 +530,7 @@ class ClearableFileInput(FileInput): input_text = _("Change") template_name = "django/forms/widgets/clearable_file_input.html" checked = False - use_fieldset = True + use_fieldset = False def clear_checkbox_name(self, name): """ diff --git a/docs/releases/5.2.10.txt b/docs/releases/5.2.10.txt index 0b7ab06d549e..6be8f7988576 100644 --- a/docs/releases/5.2.10.txt +++ b/docs/releases/5.2.10.txt @@ -4,11 +4,15 @@ Django 5.2.10 release notes *Expected January 6, 2026* -Django 5.2.10 fixes several bugs in 5.2.9. +Django 5.2.10 fixes a data loss bug in Django 5.2 and one bug related to +support for Python 3.14. Bugfixes ======== +* Fixed a bug in Django 5.2 where data exceeding ``max_length`` was silently + truncated by :meth:`.QuerySet.bulk_create` on PostgreSQL (:ticket:`33647`). + * Fixed a bug where management command colorized help (introduced in Python 3.14) ignored the :option:`--no-color` option and the :envvar:`DJANGO_COLORS` setting (:ticket:`36376`). diff --git a/docs/releases/6.0.1.txt b/docs/releases/6.0.1.txt index 753d2c87ad0e..a84b1ba6efd1 100644 --- a/docs/releases/6.0.1.txt +++ b/docs/releases/6.0.1.txt @@ -4,11 +4,14 @@ Django 6.0.1 release notes *Expected January 6, 2026* -Django 6.0.1 fixes several bugs in 6.0. +Django 6.0.1 fixes one data loss bug in Django 5.2 and several bugs in 6.0. Bugfixes ======== +* Fixed a bug in Django 5.2 where data exceeding ``max_length`` was silently + truncated by :meth:`.QuerySet.bulk_create` on PostgreSQL (:ticket:`33647`). + * Fixed a regression in Django 6.0 where :ttag:`querystring` mishandled multi-value :class:`~django.http.QueryDict` keys, both by only preserving the last value and by incorrectly handling ``None`` values (:ticket:`36783`). @@ -35,3 +38,7 @@ Bugfixes * Fixed a regression in Django 6.0 where :func:`~django.urls.path` routes defined using :func:`~django.utils.translation.gettext_lazy` failed to resolve correctly (:ticket:`36796`). + +* Fixed a regression in Django 6.0 where the :attr:`.Widget.use_fieldset` + attribute of :class:`~django.forms.ClearableFileInput` was flipped + from ``False`` to ``True`` (:ticket:`36829`). diff --git a/tests/backends/postgresql/test_compilation.py b/tests/backends/postgresql/test_compilation.py index 275660607d7e..a922df39562f 100644 --- a/tests/backends/postgresql/test_compilation.py +++ b/tests/backends/postgresql/test_compilation.py @@ -3,6 +3,7 @@ from django.db import connection from django.db.models.expressions import RawSQL +from django.db.utils import DataError from django.test import TestCase from ..models import Article, Reporter, Square @@ -48,3 +49,12 @@ def test_unnest_eligible_foreign_keys(self): self.assertEqual( [article.reporter for article in articles], [reporter, reporter] ) + + def test_parametrized_db_type(self): + with self.assertRaises(DataError): + Reporter.objects.bulk_create( + [ + Reporter(), + Reporter(first_name="a" * 31), + ] + ) diff --git a/tests/forms_tests/widget_tests/test_clearablefileinput.py b/tests/forms_tests/widget_tests/test_clearablefileinput.py index 8f2d951966e7..ae54cc4b5da9 100644 --- a/tests/forms_tests/widget_tests/test_clearablefileinput.py +++ b/tests/forms_tests/widget_tests/test_clearablefileinput.py @@ -246,19 +246,18 @@ class TestForm(Form): ) form = TestForm() - self.assertIs(self.widget.use_fieldset, True) + self.assertIs(self.widget.use_fieldset, False) self.assertHTMLEqual( - "
Field:" - '
' - "
With file:Currently: " + '
' + '
' + '
Currently: ' 'something
Change:
' - "
Clearable file:" + 'name="with_file" id="id_with_file">
' + '
' 'Currently: something' '
Change:' - '' - "
", + '', form.render(), )