django/django · Monthly · Jun 01, 2026 - Jun 30, 2026

django/django Monthly Update — June 2026 Highlights: Security Fixes, Cache Tag Improvements, and Deprecation Warnings

Commits summarized
72
Period
Jun 01 - Jun 30, 2026
Published
Jul 01, 2026

django/django Monthly Update — June 2026 Highlights

Who should read this? Django maintainers, library authors, and teams running Django in production. This issue covers security patches (CVE-2026-35193), important bug fixes, deprecation notices, documentation improvements, and test infrastructure changes from the past month.

⚠️ Security & Bug Fixes

Updated Cache-Control directive matching (CVE-2026-35193)

  • Fix for UpdateCacheMiddleware: Replaced brittle substring matching of Cache-Control directives with exact-token parsing (142b881). This prevented false positives from extended directives like myprivate.
  • Qualified directive support: Subsequent work added a split_directive_names() helper to also recognize RFC 9111 qualified forms (e.g. private="Set-Cookie"), closing an oversight in the initial fix (b461519).

Path traversal prevention in startproject/startapp

  • Switched from os.path.join() to safe_join() when handling downloaded template archives, preventing a malicious server from writing files outside the temporary directory via crafted filenames (46c5e76).

Control characters no longer written into XML attributes

  • SimplerXMLGenerator now rejects control characters in attribute values (not just element content), protecting syndication feeds and the XML serializer from producing unparseable output (67c4075).

✨ New Features & Improvements

sendtestemail now supports --using

  • The management command accepts a --using option to specify which mailer backend to test — useful when multiple backends are configured (14c6682).

Deploy-only system check for development email backends

  • Two new system checks (mail.E001) warn when the default MAILERS entry uses a non-production-ready backend like locmem or console, helping catch accidental deployment misconfiguration (61e078e).

Action now importable from django.contrib.admin

  • A convenience re-export makes it easier to reference the Action class used by admin actions (14988f1).

Reduced false positives in collectstatic string detection

  • The static files collector now better distinguishes real strings from noise, cutting down on spurious matches (f1440a7).

🐞 Notable Bug Fixes

Admin & Forms

  • db_default on primary keys: The form system now treats DatabaseDefault values as empty in Widget.format_value(), preventing garbage from appearing in input fields (71af23d). The admin also now displays db_default fields as empty (77d0c9d).
  • Media.__add__ for non-Media operands: Now returns NotImplemented instead of silently producing broken combined media lists, causing a clear TypeError (a2f8a4a).
  • GenericInlineModelAdmin.get_formset(): Now uses get_exclude() like other inline admins, fixing an inconsistency (e1df395).

Migrations

  • sqlmigrate crash on RenameModel with self-referential FK: The schema editor now records table renames during SQL collection, redirecting constraint introspection to the still-existing old table name (c6f81b3).
  • CreateModel with unique_together + AlterUniqueTogether: No longer crashes when both operations interact (cd385e6).

Caching

  • FileBasedCache.touch() for expired keys: Now handles the case gracefully instead of raising ValueError (d058058).
  • Database cache culling: Skips an unnecessary DELETE query when cull_num evaluates to zero, reducing database load (867c7c0).

Email

  • Bcc in extra_headers: Now raises ValueError because Bcc addresses must never appear in the message body — they belong only in the SMTP envelope (0943448).

Password Hashing

  • Non-UTF-8 bytes passwords: Both PBKDF2 and MD5 password hashers now accept arbitrary bytes without raising UnicodeDecodeError (356e5b0).
  • Documentation clarification: Replaced ambiguous "plain-text" with "plaintext" throughout the password hashers docs (e789914).

Template & Cache Tag

  • Netstring delimiters for {% cache %}: Switched to length-prefixed (netstring) delimiters for vary-on arguments and vary-on headers, eliminating collision bugs where argument/header values could concatenate ambiguously (8acd000, 65acb3c).

Other Fixes

  • QuerySet.aiterator(): Added missing chunk_size=None check to align with iterator() behavior (ca5746b).
  • sensitive_post_parameters no-argument form: Now correctly applies to MultiValueDict as intended (56050ac).
  • JSONL deserializer: Supports subclasses overriding _get_lines() (189c2d2).

🪓 Deprecations & Removals

  • select_related() with no arguments is now deprecated. ModelAdmin no longer emits a spurious warning when implementing its own list_select_related=True behavior (e452715, 99672c6).
  • safe parameter of JSONResponse is deprecated (c37cc70).
  • SIGNED_COOKIE_LEGACY_SALT_FALLBACK deprecation note moved to the proper location (cf88938).
  • django_file_prefixes() moved to django.utils.warnings (with a backward-compatible re-export from the old location) (f970a98).

🧪 Testing & CI

  • Geospatial library version coverage: A new CI workflow expands test coverage across GDAL/GEOS versions (f2f5228).
  • Flaky signal test fixed: gc.collect() and explicit dead-receiver cleanup now prevent timing-dependent assertion failures (15bcbee).
  • selenium<4.44.0 pin removed: Test suite no longer constrained to older Selenium (125e337).
  • Hardcoded PKs removed: 11 test files updated to avoid hardcoded primary key values (f7cb1e1).
  • tests/migrations/test_base.py renamed to base.py for consistency (7b09ce8).

📖 Documentation

New & Updated

  • Async support topics doc: Removed outdated warnings and refreshed performance guidance (2c5e4af).
  • setUpTestData as test speed-up: Revised example to better demonstrate data isolation and performance benefits (d80ef32).
  • sphinx-autobuild for auto-reloading docs: Documented the recommended workflow for live documentation previews (9676439).
  • {% cache %} tag arguments: Clarified that all arguments are stringified (0383d12).
  • get_exclude() documented: Added to base features shared by InlineModelAdmin (09efda0).
  • README Trac link improved: Made the link more newcomer-friendly (aa0efc9).
  • Security standards in release process: Documented in howto-release-django.txt (4437807).

Build & Tooling

  • Doc builds fixed for dirhtml and ReadTheDocs: The Sphinx extension now activates for any HTML-format builder, restoring broken console tabs and versionadded/versionchanged boxes (9b1db9c).
  • Windows docs build synced: make.bat html now uses -b html to match the Makefile (bc65586).
  • Sphinx < 1.8 compatibility shim removed: Cleaned up dead code from the djangodocs extension (17a56cd).
  • CI commit-message check fixed: The check-commit-suffix job now correctly scopes analysis to only the PR's commits (bfb8679).

Release Infrastructure

  • checksum.txt no longer breaks sha1sum: Reworded the git tag line so it isn't mistaken for a checksum entry (93a1751).
  • Defunct PGP keyserver replaced: Switched from pgp.mit.edu to GitHub for key import in the release script (01c3cce).
  • Stub release notes added: For upcoming 6.0.7 and 5.2.16 releases (8defe54).

📦 Performance

  • @user_passes_test async checking: Optimized to reduce overhead per decorator application (f891010).
  • CSP decorator async checking: Reduced ~1 microsecond per application by checking sync/async before creating both wrappers (b5b53af).

This update reflects a selection of 72 commits from June 2026. For the full changelog, see the django/django commit log.

Repository updates

Follow future updates

Get generated django/django development summaries by email, or follow the weekly and monthly RSS feeds.

Sign in to subscribe by email. RSS feeds are public.

Sign in to subscribe