From fe189dc43ab3eddbbceefb6834893b73ca60d5ed Mon Sep 17 00:00:00 2001 From: Nilesh Kumar Pahari Date: Mon, 26 Jan 2026 00:02:29 +0530 Subject: [PATCH 1/4] Fixed #36847 -- Ensured auto_now_add fields are set on pre_save(). Regression in 94680437a45a71c70ca8bd2e68b72aa1e2eff337. Refs #27222. During INSERT operations, `field.pre_save()` is called to prepare values for db insertion. The `add` param must be `True` for `auto_now_add` fields to be populated. The regression commit passed `False`, causing `auto_now_add` fields to remain `None` when used by other fields, such as `upload_to` callables. Thanks Ran Benita for the report. --- django/db/models/base.py | 4 +++- docs/releases/6.0.2.txt | 3 +++ tests/model_fields/models.py | 10 ++++++++++ tests/model_fields/test_filefield.py | 8 +++++++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/django/db/models/base.py b/django/db/models/base.py index ad3f0c5e23a1..d53da600d792 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1175,7 +1175,9 @@ def _save_table( ].features.can_return_columns_from_insert for field in insert_fields: value = ( - getattr(self, field.attname) if raw else field.pre_save(self, False) + getattr(self, field.attname) + if raw + else field.pre_save(self, add=True) ) if hasattr(value, "resolve_expression"): if field not in returning_fields: diff --git a/docs/releases/6.0.2.txt b/docs/releases/6.0.2.txt index b25f1af472b6..d74a8bd76345 100644 --- a/docs/releases/6.0.2.txt +++ b/docs/releases/6.0.2.txt @@ -15,3 +15,6 @@ Bugfixes to wrap below the changelist when filter elements contained long text (:ticket:`36850`). +* Fixed a regression in Django 6.0 where ``auto_now_add`` field values were not + populated during ``INSERT`` operations, due to incorrect parameters passed to + ``field.pre_save()`` (:ticket:`36847`). diff --git a/tests/model_fields/models.py b/tests/model_fields/models.py index 1d8a447dee8b..a594b89adb0d 100644 --- a/tests/model_fields/models.py +++ b/tests/model_fields/models.py @@ -262,10 +262,20 @@ class DataModel(models.Model): # FileField +def upload_to_with_date(instance, filename): + return f"{instance.created_at.year}/{filename}" + + class Document(models.Model): myfile = models.FileField(storage=temp_storage, upload_to="unused", unique=True) +# See ticket #36847. +class DocumentWithTimestamp(models.Model): + created_at = models.DateTimeField(auto_now_add=True) + myfile = models.FileField(storage=temp_storage, upload_to=upload_to_with_date) + + ############################################################################### # ImageField diff --git a/tests/model_fields/test_filefield.py b/tests/model_fields/test_filefield.py index 57cc7365da15..fbf5c837ac57 100644 --- a/tests/model_fields/test_filefield.py +++ b/tests/model_fields/test_filefield.py @@ -13,7 +13,7 @@ from django.test import TestCase, override_settings from django.test.utils import isolate_apps -from .models import Document +from .models import Document, DocumentWithTimestamp class FileFieldTests(TestCase): @@ -209,3 +209,9 @@ class MyDocument(AbstractMyDocument): document = MyDocument(myfile="test_file.py") self.assertEqual(document.myfile.field.model, MyDocument) + + def test_upload_to_callable_sees_auto_now_add_field_value(self): + d = DocumentWithTimestamp(myfile=ContentFile(b"content", name="foo")) + d.save() + self.assertIsNotNone(d.created_at) + self.assertIs(d.myfile.name.startswith(f"{d.created_at.year}/foo"), True) From ba9637901113deb9ae808b2ba1798c18dc85a915 Mon Sep 17 00:00:00 2001 From: Natalia <124304+nessita@users.noreply.github.com> Date: Wed, 28 Jan 2026 22:42:41 -0300 Subject: [PATCH 2/4] Fixed docs spelling errors accumulated over time. The `docs` GitHub action does not install `aspell` so the seplling checks are always passing in CI. After installing it, the following errors are reported: WARNING: internals/security.txt:50: : Spell check: runnable: Include a runnable proof of concept. WARNING: ref/contrib/postgres/search.txt:292: : Spell check: lexeme: an untrusted source. The content of each lexeme is escaped so that any. WARNING: ref/contrib/postgres/search.txt:295: : Spell check: lexemes: You can combine lexemes with other lexemes using the . WARNING: ref/contrib/postgres/search.txt:295: : Spell check: lexemes: You can combine lexemes with other lexemes using the . WARNING: ref/contrib/postgres/search.txt:314: : Spell check: Lexeme: Lexeme objects also support term weighting and prefixes:. WARNING: ref/models/database-functions.txt:1897: : Spell check: ai: 23ai/26ai (23.9) or later.. WARNING: ref/models/database-functions.txt:1897: : Spell check: ai: 23ai/26ai (23.9) or later.. WARNING: ref/models/expressions.txt:439: : Spell check: positionally: can be supplied positionally or only by keyword. For. WARNING: ref/models/fields.txt:1339: : Spell check: ai: PostgreSQL < 18 only supports persisted columns. Oracle < 23ai/26ai (23.7). WARNING: ref/models/fields.txt:1339: : Spell check: ai: PostgreSQL < 18 only supports persisted columns. Oracle < 23ai/26ai (23.7). WARNING: ref/models/fields.txt:1344: : Spell check: ai: s was added on Oracle 23ai/26ai. WARNING: ref/models/fields.txt:1344: : Spell check: ai: s was added on Oracle 23ai/26ai. WARNING: releases/4.2.21.txt:24: : Spell check: unclosed: exception if it encounters an unusually large number of unclosed opening tags.. WARNING: releases/5.1.9.txt:24: : Spell check: unclosed: exception if it encounters an unusually large number of unclosed opening tags.. WARNING: releases/5.2.1.txt:24: : Spell check: unclosed: exception if it encounters an unusually large number of unclosed opening tags.. WARNING: releases/6.1.txt:244: : Spell check: mistyped: suggestions for mistyped subcommand names and argument choices.. WARNING: releases/6.1.txt:281: : Spell check: ai: Oracle 23ai/26ai (23.7+).. WARNING: releases/6.1.txt:281: : Spell check: ai: Oracle 23ai/26ai (23.7+).. WARNING: releases/6.1.txt:343: : Spell check: durations: durations expressed in weeks (. WARNING: Found 19 misspelled words build finished with problems, 20 warnings (with warnings treated as errors). This branch adds some of the words to the allowlist, but for others I chose to rephrase the text in a more approachable manner. --- docs/internals/security.txt | 4 ++-- docs/ref/models/expressions.txt | 10 +++++----- docs/releases/6.1.txt | 4 ++-- docs/spelling_wordlist | 4 ++++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/internals/security.txt b/docs/internals/security.txt index 4eee3947596d..a3d57e8d7c4f 100644 --- a/docs/internals/security.txt +++ b/docs/internals/security.txt @@ -46,8 +46,8 @@ the industry-standard 90 days. Confirmed vulnerabilities with a Reporting guidelines -------------------- -Include a runnable proof of concept -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Include a working proof of concept +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Please privately share a minimal Django project or code snippet that demonstrates the potential vulnerability. Include clear instructions on how to diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index 3238207c5b3a..81aa3a92b2c2 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -438,11 +438,11 @@ return type. Built-in database functions (such as :class:`~django.db.models.functions.Cast`) vary in whether arguments such - as ``output_field`` can be supplied positionally or only by keyword. For - ``output_field`` and several other cases, the input ultimately reaches - ``Func()`` as a keyword argument, so the advice to avoid constructing - keyword arguments from untrusted user input applies as equally to these - arguments as it does to ``**extra``. + as ``output_field`` can be supplied as positional arguments or only by + keyword. For ``output_field`` and several other cases, the input ultimately + reaches ``Func()`` as a keyword argument, so the advice to avoid + constructing keyword arguments from untrusted user input applies as equally + to these arguments as it does to ``**extra``. ``Aggregate()`` expressions --------------------------- diff --git a/docs/releases/6.1.txt b/docs/releases/6.1.txt index a1f8672e8cde..ca9ba16e84e0 100644 --- a/docs/releases/6.1.txt +++ b/docs/releases/6.1.txt @@ -242,7 +242,7 @@ Management Commands * Management commands now set :class:`~argparse.ArgumentParser`\'s ``suggest_on_error`` argument to ``True`` by default on Python 3.14, enabling - suggestions for mistyped subcommand names and argument choices. + suggestions for incorrectly typed subcommand names and argument choices. * The :djadmin:`loaddata` command now calls :data:`~django.db.models.signals.m2m_changed` signals with ``raw=True`` when @@ -340,7 +340,7 @@ Utilities ~~~~~~~~~ * :func:`~django.utils.dateparse.parse_duration` now supports ISO 8601 - durations expressed in weeks (``PnW``). + time periods expressed in weeks (``PnW``). Validators ~~~~~~~~~~ diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist index f9eabf483b06..7024060ff5c7 100644 --- a/docs/spelling_wordlist +++ b/docs/spelling_wordlist @@ -4,6 +4,7 @@ accessors Aceh admindocs affordances +ai Ai Alchin allowlist @@ -245,6 +246,8 @@ kwargs Kyrgyz latin lawrence +lexeme +lexemes Libera lifecycle lifecycles @@ -531,6 +534,7 @@ unapplied unapplying uncategorized unclaim +unclosed uncopyable unencoded unencrypted From 117ff1d37d63cdfa0982eba6b636bf8f59d99a3c Mon Sep 17 00:00:00 2001 From: Natalia <124304+nessita@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:04:47 -0300 Subject: [PATCH 3/4] Made explicit that aspell is a requirement to run spell checks on docs. --- docs/internals/contributing/writing-documentation.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/internals/contributing/writing-documentation.txt b/docs/internals/contributing/writing-documentation.txt index 09a790b4a36d..90e9533db810 100644 --- a/docs/internals/contributing/writing-documentation.txt +++ b/docs/internals/contributing/writing-documentation.txt @@ -178,8 +178,9 @@ Spelling check ~~~~~~~~~~~~~~ Before you commit your docs, it's a good idea to run the spelling checker. -You'll need to install :pypi:`sphinxcontrib-spelling` first. Then from the -``docs`` directory, run: +You'll need to install :pypi:`sphinxcontrib-spelling` first. The spell checker +also requires a system-level spell checking backend such as `Aspell +`__. Then from the ``docs`` directory, run: .. console:: From f87c2055b45356378a7c2a020eb872352d20f85e Mon Sep 17 00:00:00 2001 From: Natalia <124304+nessita@users.noreply.github.com> Date: Wed, 28 Jan 2026 22:24:26 -0300 Subject: [PATCH 4/4] Fixed spell checking in docs GitHub Actions workflow. The spelling check job was passing even with spelling errors because the system spell checker (`aspell`) was not installed on the GitHub Actions runner. While `sphinxcontrib.spelling` and `PyEnchant` were installed via pip, they require a system-level spell checker backend to function. --- .github/workflows/docs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ffbb8450881f..09ec383a79f2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -35,6 +35,8 @@ jobs: python-version: '3.14' cache: 'pip' cache-dependency-path: 'docs/requirements.txt' + - name: Install system spell checker + run: sudo apt update && sudo apt install -y aspell aspell-en - run: python -m pip install -r docs/requirements.txt - name: Build docs run: |