31 May 2026
Django community aggregator: Community blog posts
Django: introducing django-integrity-policy
Back in January, Firefox's Security & Privacy Newsletter for 2025 Q4 piqued my interest with this mention:
Integrity-Policy: Firefox 145 has added support for the Integrity-Policy response header. The header allows websites to ensure that only scripts with an integrity attribute will load.
A new security header! That's right up my street: I've cared about getting security headers right since 2018, when I created django-permissions-policy to set the Permissions-Policy header. (At the time, it was called Feature-Policy: why they changed it, I can't say, people just liked it better that way.)
The new Integrity-Policy header helps with subresource integrity, a tool for securely including third-party scripts and stylesheets on your website. Browsers support the integrity attribute on <script> and <link> tags, which allows you to specify a hash of the expected content, like:
<script
src=https://cdn.jsdelivr.net/npm/htmx.org@4.0.0-beta4/dist/htmx.min.js
integrity=sha384-aWZK1NtOs/aWb/+YZdTM8q2JkWEshlMc9mgZ189numT9bwFhyAyYEoO4nO/2dTXt
crossorigin=anonymous></script>
If the content downloaded from the external source doesn't match the expected hash, the browser blocks it from loading. This is a great defense against the target URL changing its contents, executing a supply chain attack against your visitors.
(Generally, I recommend you avoid loading anything from a third-party URL, per Reasons to avoid Javascript CDNs. But sometimes, you gotta do what you gotta do, and declaring integrity is a great idea, then.)
Integrity-Policy allows you to opt in to requiring integrity attributes on your page, ensuring that you can never load potentially-compromised resources. The header is fairly simple, at least right now-here's a complete example that requires integrity for all scripts and stylesheets:
Integrity-Policy: blocked-destinations=(script style)
You can add in endpoints to tell browsers where to send violation reports to, and there's the second Integrity-Policy-Report-Only header which lets you test a policy without enforcing it.
Note there's no possibility to differentiate between first- and third-party resources in Integrity-Policy. If you set it, you'll need to add integrity attributes to all your scripts and stylesheets, including those you host yourself. This is by design: the header is being developed as part of Web Application Integrity, Consistency and Transparency (WAICT), an initiative to bring app-store-level "code signing" to the web, where users can be sure that CDNs and other intermediaries haven't tampered with served code.
Integrity-Policy is supported on Firefox 145+ and Chrome 138+.
django-integrity-policy
My new package, django-integrity-policy provides a middleware for setting the Integrity-Policy headers in a familiar Django-style way. You install it, add the middleware:
MIDDLEWARE = [
...,
"django.middleware.security.SecurityMiddleware",
"django_integrity_policy.IntegrityPolicyMiddleware",
...,
]
β¦and then configure the appropriate setting(s):
INTEGRITY_POLICY = {
"blocked-destinations": ["script", "style"],
}
So far, it's pretty basic, but I expect WAICT will increase the complexity of Integrity-Policy over time, and I'll add support for new options as they come along.
Once Integrity-Policy is set, the browser will block any scripts or stylesheets (depending on configuration) that lack a valid integrity attribute, including your first-party resources. That means you need to add integrity attributes to all your static files. Luckily, this has been considered before by the legendary Jake Howard, who made a package called django-sri. It provides template tags to generate appropriately hashed HTML tags. For example:
{% load sri %}
{% sri_static "app.js" %}
{% sri_static "app.css" %}
β¦will output:
<script src="/static/app.js" integrity="sha256-..."></script>
<link rel="stylesheet" href="/static/app.css" integrity="sha256-..."/>
These tags would be allowed under a maximally strict integrity policy.
See the example application in the django-integrity-policy repository for a full working project.
LLM generation
I built this package using just two prompts to Claude. I copied the repository for my previous security header package, django-permissions-policy, and reset its Git history. I then used this prompt to Claude, inside Zed:
The current repository is a copy of my package django-permissions-policy
It's time to turn it into django-integrity-policy, for the relevant headers per the below mdn docs
(Integrity-Policy MDN docs from https://github.com/mdn/content/blob/main/files/en-us/web/http/reference/headers/integrity-policy/index.md?plain=1)
(Integrity-Policy-Report-Only MDN docs from https://github.com/mdn/content/blob/main/files/en-us/web/http/reference/headers/integrity-policy-report-only/index.md?plain=1)
Check and edit every file to be that new package, copyright 2026, keeping the general testing infrastructure and so on.
Don't run any commands yet, just check and edit every file
I then took a 20-minute nap and woke up to a near-complete package. I reviewed it, ran the tests, made some minor edits, committed, and pushed to PyPI!
LLMs are rightfully a hot topic, with heady supporters and heavy detractors. I use them begrudgingly and somewhat sparingly, and I cannot wait for the future where I can stick to local models. (Gemma 4 can run on my M1 Mac and approaches Claude's performance on many tasks, so we're getting there.)
This task, though, was a perfect fit for LLM code generation: the existing repository acted as great context for structure, the new package was very similar in shape ("same same but different"), and the documentation provided a clear specification for what to build. The LLM could mash things up for me with minimal oversight, and I could check the work quickly.
I would guess that overall, using an LLM saved me a couple of hours of mostly grunt-work, like checking every copied-over configuration file. That's pretty valuable for me, and honestly made creating the package feasible.
The future
I'm not sure how widely used Integrity-Policy will be, and therefore how popular django-integrity-policy will end up. But this was an interesting exercise and I am interested to see how the header and other work from WAICT evolves. I will try to keep the package updated, and we'll see if it ever reaches a point where proposing support in Django itself makes sense.
31 May 2026 4:00am GMT
29 May 2026
Django community aggregator: Community blog posts
Issue 339: Early Bird DjangoCon US Tickets Ending Soon
News
DjangoCon US 2026: Early Bird Tickets End May 31st!
Early bird ticket sales for DjangoCon US 2026 end on May 31, 2026, with discounted pricing available. The conference runs five days at Voco Chicago Downtown and includes community-selected talks plus Django contribution sprints.
Wagtail CMS News
Wagtail Space NL - June 12
A full-day conference in Rotterdam, The Netherlands on Wagtail, with talks covering a range of topics, lightning talks, hallway discussions, and more.
Updates to Django
Today, "Updates to Django" is presented by Pradhvan from Djangonaut Space! π
Last week we had 16 pull requests merged into Django by 10 different contributors.
This week's Django highlights: π¦
- Django's built-in error pages, admin, and registration templates now include the CSP nonce on
<script>,<link>, and<style>elements when available. (#36825) - Fixed
HttpResponse.reason_phraseto raiseBadHeaderErrorwhen set to a value containing control characters. (#37100) - Fixed
Query.clear_ordering()to recursively clear ordering on combined queries, preventing errors when using__inlookups on nestedunion()querysets. (#37097) - Admin change form actions now use
ModelAdmin.get_queryset(), ensuring custom annotations and filtering are consistently applied to form actions. (#37117)
If you haven't already, give Django 6.1 alpha 1 a spin and report anything suspicious to the issue tracker! π
That's all for this week in Django development! ππ¦
Articles
Upgrade PostgreSQL from 17 to 18 on Ubuntu 26.04
After moving to Ubuntu 26.04, upgrade an existing 17/main cluster to 18 by running pg_upgradecluster 17 main -v 18, then verify the new 18/main cluster is online. Once confirmed, drop the old 17 cluster with pg_dropcluster 17 main and optionally purge postgresql-17 and postgresql-client-17 packages.
My not-so-static new static website
Jake Howard walks through his eighth website rewrite, this time ditching Wagtail for a custom "semi-static" Django setup that renders Markdown content into SQLite at startup and serves it dynamically with Jinja2 templates.
Improving First Byte and Contentful Paint on a Django Website
A look at how to use Django's StreamingHttpResponse to send the ` and above-the-fold content first, letting the browser fetch static assets and start painting while the rest of the page renders.
PyCon US 2026 Recap - Black Python Devs
A recap from from the community booth to open spaces, hallway track, and Jay Miller receiving the PSF Community Service Award.
django-removals 1.2.0 - Now with Django 6.1 deprecations
How the maintainers of django-removals shipped new warnings for the Django 6.1 deprecation wave.
Mentoring GSoC 2026: Experimental Flags - Software Crafts
Mentor and mentee are starting a GSoC 2026 project around an "Experimental Flags" framework for Django core, using the forum to gather requirements and drive early consensus. The plan balances fast iteration with faster-than-normal Django consensus, including an initial third-party package to test ideas before wider adoption.
Django Forum
GSoC 2026: Implementing a Formal Experimental API Framework for Django Core
A lively discussion around how experimental features can be merged into the main repository but remain explicitly non-stable.
Thoughts on advertising on djangoproject.com
New thoughts and comments on the age-old question.
Django Fellow Reports
Jacob Walls
Not much going on, "just" the 6.1 Feature Freeze/alpha release, a sprint at PyCon US, and a kickoff meeting with Google Summer of Code participants & mentors.
Sarah Boyce
As we had the feature freeze, focused on a few feature PRs I had prioritized for 6.1 release.
Natalia Bidart
This week was mostly about returning from PyCon, which was quite exhausting. I arrived back on Wednesday, fairly drained (and very hungry), so I worked during Thu and Fri catching up on a large backlog of email notifications and syncing with the other Fellows.
Events
Django on the Med - September 23-25 in Pescara, Italy
PyCon Italia this week has been Django members in attendance, so it is a good time to remind readers that Django on the Med will be back in Italy later in the year.
Django Job Board
Founding Engineer at MyDataValue
Projects
feincms/feincms3-cookiecontrol
Cookie banner with support for embedded media.
emfpdlzj/django-deploy-probes
HTTP deployment probes for Django applications.
29 May 2026 2:00pm GMT
27 May 2026
Django community aggregator: Community blog posts
Please add an RSS Feed to Your Site
Why syndication feeds are having a moment in 2026.
27 May 2026 9:57pm GMT