09 Jan 2026
Django community aggregator: Community blog posts
Django News - Django Bugfixes, Community Wins, and What’s NextIssue 319 - Jan 9th 2026
News
Django bugfix releases issued: 5.2.10, 6.0.1
Django released bugfix updates 5.2.10 and 6.0.1; release packages and signed checksums are available on the downloads page and PyPI.
DjangoCon US 2026 Call for Proposals
The CFP is now open until March 16, 2026. The conference this year will be September 14-18, again in Chicago.
Wagtail CMS News
Wagtail Wrapped 2025
Wagtail's 2025 recap highlights four releases culminating in 7.2 with a 7.0 LTS, deferred validation toward autosave, search revamp, and AI package improvements.
Updates to Django
Today, "Updates to Django" is presented by Raffaella from Djangonaut Space! 🚀
Last week we had 6 pull requests merged into Django by 5 different contributors - including a first-time contributor! Congratulations to Mykhailo Havelia for having their first commits merged into Django - welcome on board!
- Fixed a bug in Django 5.2 where data exceeding
max_lengthwas silently truncated byQuerySet.bulk_create()on PostgreSQL (#33647). - Fixed a regression in Django 6.0 where the
Widget.use_fieldsetattribute ofClearableFileInputwas flipped fromFalsetoTrue(#36829).
Django Newsletter
Articles
Migrating From Celery to Django Tasks
Django's new Task Framework makes it surprisingly easy to replace Celery, covering configuration, task migration, queues, workers, and periodic jobs with simpler, built-in tooling.
My 2025 year in review - Andrew Miller
Andy's recap of regular blogging, conference attending, working on a financial services startup, using AI, publishing django-prodserver, and more in 2025.
Ceci n'est pas un blog
Russell Keith-Magee shares that receiving Django commit access 20 years ago set a trajectory that led to remote roles, startups, BeeWare, and continued open-source impact.
Open Source Is People: A Python & Django Year
Anthony Addae describes a 2025 journey from mentoring to becoming an active Django contributor and organizer, including participation in Djangonaut Space and a first Django core pull request.
Django Quiz 2025
Adam Johnson shares the 2025 edition of his annual Django pop quiz from Django London, inviting readers to test their Django knowledge with a mix of fun, community-focused, and framework-wide questions.
What async really means for your python web app? - hackeryarn
Async Python web benchmarks show that for most Django apps hitting a database, well-tuned synchronous setups with connection pooling outperform async frameworks, making async far from the free performance win many expect.
Events
Things I'd Like to See in a DjangoCon US 2026 Talk
Curated talk ideas for DjangoCon US 2026 CFP covering deployment, Django 6.x features, performance, security, HTMX, type checking, ML, and community topics.
Django Job Board
Explore senior Python and Django roles spanning enterprise, open web infrastructure, and a fully remote UK-based startup.
Senior Python Developer at Cial Dun & Bradstreet
Software Engineer at Internet Archive
Founding Full-Stack Senior Engineer (UK ONLY) - Fully Remote at MyDataValue
Django Newsletter
Projects
Django on the Fediverse - Mastodon Starter Pack
Curated starter pack of nonhuman Django accounts on the Fediverse listing official projects, conferences, media, and community hubs.
kraken-tech/django-pg-migration-tools
Extra functionalities to make Django migrations safer and more scalable.
amureki/django-devbar
Lightweight performance devbar for Django.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
09 Jan 2026 5:00pm GMT
08 Jan 2026
Django community aggregator: Community blog posts
Documenting Django's technical culture
Following along the lines from one of posts from last year about Django being a protocol or an API, there was a recent discussion on Mastodon about configurable content types, and there's a ticket in flight to implement this new feature that would make content types configurable. This made me think, in django-prodserver, I'm already creating configurable backends, and in Django generally we have configurable components: databases, caches, storage backends, email backends, and so on. Most of whole system is configurable, and the INSTALLED_APPS setting could be considered the heart of this.
I see some potential value in building out a meta design documents for how we expect new features to be built in Django, describing the kinds of designs or Python APIs we would anticipate in feature. For example, there's clearly a pattern of a configurable backend via settings, as I mentioned. But are there other conventions we should codify? Whether that takes the form of a contribution document, or an issue template in GitHub, but I think starting with some documentation would be a good start. It might also reveal some gaps in existing features that don't meet the standard we would expect for new features being introduced.
I'm wondering if this is something people are interested in, or something that could smooth the adoption of a package into core though I won't claim it would speed things up, given how we pace ourselves. We do have established patterns; codifying them a bit more could help those who want to contribute back. Although this is a technical document, it serves more as a community document that shares our culture of how we build Django, therefore creating another on ramp for the community.
08 Jan 2026 6:00am GMT
03 Jan 2026
Django community aggregator: Community blog posts
Django Quiz 2025
Last month, I held another quiz at the December edition of Django London. The December quiz is an annual tradition at our meetup, a way of making this final event of the year more relaxed and giving away some nice prizes. This was the seventh quiz that I've presented, and the eighth overall.
Here's an action shot taken by one of my co-organizers:

Below is the quiz itself, so you can try it at home. Answers follow at the end, with some extra explanation. Dates refer to December 2025, so if you're reading in the future, take that into consideration. (Posting a little late this time, so happy new year!)
Enjoy!
The quiz
2. Which of these databases does core Django support?
- MongoDB
- Oracle
- Microsoft SQL Server
- A bunch of YAML files
3. Which of the below names is not a current Django Fellow?
- Jacob Tyler Walls
- Natalia Bidart
- Sarah Boyce
- Django Reinhardt
4. Who manages the Django project?
- The Python Software Foundation
- Adrian Holovaty
- The Django Software Foundation
- Anyone who lists Django as a skill on LinkedIn
6. What is the modern API for HTTP request headers?
request.hrequest.METArequest.headersrequest.get_me_a_header
7. What does CSP stand for?
- Content Security Policy
- Contributed Security Patches
- Callable Script Parameters
- Crazy Secure Python
8. What is the new decorator to define a background task?
@task@background_task@background@do_it_later
9. In which city will DjangoCon Europe 2026 be held?
- Athens, Greece
- Zagreb, Croatia
- Dublin, Ireland
- Hell, Norway
10. How do you use Django's test client to make a GET request?
Client.get(url)self.client.get(url)self.client.fetch("GET", url)llm.prompt(f"Check this URL with GET: {url}")
Okay, now the answers
1. How old is Django this year?
🎂 Django was released in December 2005, making it 20 years old this year.
2. Which of these databases does core Django support?
Django has supported Oracle since 2006!
3. Which of the below names is not a current Django Fellow?
Django Reinhardt was a jazz guitarist, from whom the framework takes its name. Jacob Tyler Walls, Natalia Bidart, and Sarah Boyce are the current Django Fellows.
4. Who manages the Django project?
The Django Software Foundation is a US non-profit with the aim of promoting, supporting, and advancing the Django web framework.
5. What is the latest version of Django?
Django 6.0 is the latest version, as of December 3rd, 2025. See my "what's new post" for highlights.
6. What is the modern API for HTTP request headers?
request.headers is the new apprach, added in Django 2.2 (2019), superseding the older request.META approach. It acts as a case-insensitive mapping. For example, to access the User-Agent header:
def index(request):
user_agent = request.headers.get("user-agent", "")
...
7. What does CSP stand for?
CSP stands for Content Security Policy, a security feature that helps prevent XSS attacks, as newly supported in Django 6.0!
8. What is the new decorator to define a background task?
The @task decorator is new in Django 6.0 for defining background tasks, which you can use like:
from django.tasks import task
from example.models import User
@task
def send_welcome_email(user_id):
user = User.objects.get(id=user_id)
...
9. In which city will DjangoCon Europe 2026 be held?
DjangoCon Europe 2026 will be held in Athens, Greece. See you there?
10. How do you use Django's test client to make a GET request?
A testing classic! Use self.client.get(url) to make a GET request with Django's test client, like:
from django.test import TestCase
class IndexTests(TestCase):
def test_success(self):
response = self.client.get("/index/")
assert response.status_code == 200
...
11. Which ORM method returns a dictionary of PKs to model instances?
The Model.objects.in_bulk() method returns a dictionary of primary keys to model instances. For example:
In [1]: Book.objects.in_bulk([1, 2, 3])
Out[1]:
{1: <Book: Brave New World (id=1)>,
2: <Book: Slaughterhouse-Five (id=2)>,
3: <Book: 1984 (id=3)>}
12. What's the HTML tag for a dialog?
The <dialog> element has been available since 2022, and was extended by the Invoker Commands API this year. You can now make a <dialog> that is opened by a <button> without any JavaScript like so:
<button commandfor=subscribers command=show-modal>
View subscribers
</button>
<dialog id=subscribers>
<button commandfor=mydialog command=close>Close</button>
<h2>Subscribers</h2>
<!-- Insert contents here -->
</dialog>
Short, sweet, and powerful.
Fin
I hope you have enjoyed reading through doing this quiz. You can see the previous year's quizzes in the "related posts" section below.
May your 2026 be filled with many joyful hours building with Django,
-Adam
03 Jan 2026 6:00am GMT
02 Jan 2026
Django community aggregator: Community blog posts
Django News - 🎮 Django Is Now a Video Game Framework - Jan 2nd 2026
News
DSF member of the month - Clifford Gama
Clifford Gama, DSF member and Triage and Review contributor, merged several Django core PRs and investigates performance and WeasyPrint PDF generation improvements.
PyPI in 2025: A Year in Review - The Python Package Index Blog
PyPI strengthened security and organization features in 2025, adding trusted publishing, attestations, improved 2FA, malware response, and organization management enhancements.
Updates to Django
Today, "Updates to Django" is presented by Raffaella from Djangonaut Space! 🚀
Last week we had 19 pull requests merged into Django by 15 different contributors - including 5 first-time contributors! Congratulations to Duane Hilton, Ankan Giri, guro-Ishiguro, Sean Reed, and Yilei for having their first commits merged into Django - welcome on board!
News in Django 6.0:
- Fixed a regression where
path()routes defined usinggettext_lazy()failed to resolve correctly (#36796). - Fixed a regression that caused
bulk_create()to crash when introspecting the connection on SQLite (#36818). - Fixed a crash caused by infinite recursion when calling
repr()on an unevaluateddjango.utils.csp.LazyNonce instance (#36810). - Fixed a bug where management command colorized help (introduced in Python 3.14) ignored the
--no-coloroption and theDJANGO_COLORSsetting (#36376). - Fixed a visual regression for admin form fields grouped under a
<fieldset>in Safari (#36807). - The
iexact=Nonelookup onJSONFieldkey transforms now matches JSONnull, to match the behavior ofexact=Noneon key transforms. Previously, it was interpreted as anisnulllookup.
Django Newsletter
Articles
DOOM in Django: testing the limits of LiveView at 600.000 divs/seconds
Yep, DOOM in Django. That's right. Django LiveView streams ViZDoom as 100x100 pixel frames mapped to 10,000 divs at 60 FPS, sustaining about 600000 divs per second reliably.
Django is now a video game framework.
How uv got so fast
uv achieves orders of magnitude faster Python installs by leveraging modern packaging standards, dropping legacy compatibility, and using parallel downloads, global caching, and Rust optimizations.
Django On The Med: A Contributor Sprint Retrospective
A personal retrospective on Django On The Med, three months later. From the first idea to the actual contributor sprint, and how a simple format based on focused mornings and open afternoons created unexpected value for people and the Django open source community.
Raffi's 2025 Recap ✨
Raffi reflects on a busy and rewarding 2025 filled with speaking at and attending major Django and Python conferences, organizing and volunteering across community initiatives, contributing to Django News, and building small tools to support sustainable open source work.
Ryan Cheley's Year in Review 2025
Ryan reflects on a milestone year spanning a long-awaited promotion into senior leadership, major infrastructure and healthcare IT wins, deepening involvement in the Django community including talks and DSF board leadership, a self-hosting migration, and meaningful family, music, and hockey moments that set the tone for a more intentional 2026.
Priya's My First Newsletter (And 2025 Archive)
Priya summarizes 2025 work on Djangonaut Space, community focused conference talks, CI/CD ops notes, and her election to the 2026 Django Software Foundation Board.
Tim Schilling's 2025 - My year in review
Tim Schilling reflects on a year defined by trying new things, from major personal changes and extensive travel to deep community leadership across DjangoCon, Djangonaut Space, the Steering Council, and multiple open-source projects.
Jake versus 2025
Jake's 2025 year-in-review reflects a whirlwind year of personal milestones and deep Django community impact, from buying a house and running a half marathon to shipping django.tasks, joining the Django security team, speaking at PyCon UK, and navigating how AI is reshaping the web and independent publishing.
Django Job Board
Senior Python Developer at Cial Dun & Bradstreet
Software Engineer at Internet Archive
Founding Full-Stack Senior Engineer (UK ONLY) - Fully Remote at MyDataValue
Python/Django Senior Application Security Engineer at Energy Solutions
Python / Django Developer at Client of Foxley Talent
Staff Software Engineer at Bluebird Kids Health
Django Newsletter
Projects
tanrax/django-interactive-frameworks-benchmark
Performance comparison of Django's main interactive frameworks: LiveView, Reactor, django-htmx, Unicorn, and SSR.
smattymatty/Django-Mercury-Performance-Testing
Quickly & Ergonomically transform your Django Tests to track performance statistics like response time, queries, memory usage, and more! Optional Educational Guidance for Beginners, teaching good Performance Practices for Django Models, Views, and Serializers.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
02 Jan 2026 5:00pm GMT
30 Dec 2025
Django community aggregator: Community blog posts
Django On The Med: A Contributor Sprint Retrospective
A personal retrospective on Django On The Med, three months later. From the first idea to the actual contributor sprint, and how a simple format based on focused mornings and open afternoons created unexpected value for people and the Django open source community.
30 Dec 2025 5:00am GMT
26 Dec 2025
Django community aggregator: Community blog posts
Django News - Happy Holidays and 95% there! - Dec 26th 2025
News
Hitting the Home Stretch: Help Us Reach the Django Software Foundation's Year-End Goal!
Since last week, the Django Software Foundation has reached 95% of its goal, and I appreciate your consideration in helping it meet the remaining 5%.
DjangoCon Europe - Call for Proposals
The Call for Proposals (CFP) for DjangoCon Europe 2026 is officially open! This event will be in Athens, Greece, from April 15-19, 2026. Submission deadline: Sunday, February 8, 2026 (end of day)
Updates to Django
Today, "Updates to Django" is presented by Raffaella from Djangonaut Space! 🚀
Last week we had 16 pull requests merged into Django by 15 different contributors - including 4 first-time contributors! Congratulations to H. White, Krishnaprasad MG, Jonathan Biemond, and Nilesh Pahari for having their first commits merged into Django - welcome on board!
News in Django 6.0:
- Fixed a regression that prevented changing the name of a
ManyToManyFieldfrom taking effect when applying migrations. (#36800) - Fixed a regression where
querystringmishandled multi-valueQueryDictkeys, both by only preserving the last value and by incorrectly handling None values (#36783).
News in Django 6.1:
- The
m2m_changedsignal now receives arawargument. parse_duration()now supports ISO 8601 durations expressed in weeks (PnW).- The
loaddatacommand now callsm2m_changedsignals withraw=Truewhen loading fixtures.
Django Newsletter
Articles
Querying Django Tasks
Django 6.0's new tasks framework makes it possible to discover, inspect, and run tasks across your project without Celery, and this post shows how to programmatically find and execute those tasks using app imports and backend-aware Task inspection.
Speed or Power? With Django, you don't have to choose. 🚀
Django's batteries included design lets developers move fast while still delivering secure, scalable, and production ready web applications.
PEP 770 Software Bill‑of‑Materials (SBOM) data from PyPI, Fedora, and Red Hat
PEP 770 is now live, enabling standardized SBOMs inside Python wheels, with early adoption across PyPI, auditwheel, Fedora, and Red Hat to improve supply chain transparency and reduce vulnerability scan false positives.
Getting Started with Django - Project Setup
A beginner-friendly walkthrough that shows how to set up a clean Django project from scratch using virtual environments, a flat project layout, and a quick sanity check with the development server.
My DjangoCon Africa 2025, and UbuCon Africa 2025
Personal recap of DjangoCon Africa 2025 highlighting community driven talks, accessible Django contributions, secure Metabase embeddings, workshops that enabled beginners to contribute to open source.
My 2026 year in review
A solo Django developer reflects on a packed 2025, covering consistent blogging, AI-assisted product building, community involvement at DjangoCon Europe, and lessons learned balancing startups, client work, and open source.
Events
DjangoCon US: Call for Venue Proposals 2027-28
DjangoCon US 2026 is tentatively planning to return to Chicago. Where will we be the following year or two? We need your help in making that decision!
Podcasts
Django Chat #192: From Bootcamp to Project Manager - Keanya Phelps
Keanya is a project manager at Caktus Group and Chair of DjangoCon US this year. We discuss her transition into coding via a bootcamp, working as a software engineer, using AI on the job, and her current role as a project manager.
Django Job Board
We've got a fresh batch of new Python and Django roles this week, including senior, security-focused, and founding engineer positions across remote and hybrid teams.
Senior Python Developer at Cial Dun & Bradstreet 🆕
Software Engineer at Internet Archive 🆕
Founding Full-Stack Senior Engineer (UK ONLY) - Fully Remote at MyDataValue 🆕
Python/Django Senior Application Security Engineer at Energy Solutions
Python / Django Developer at Client of Foxley Talent
Staff Software Engineer at Bluebird Kids Health
Django Newsletter
Projects
loopwerk/django-generic-notifications
A flexible, multi-channel notification system for Django applications with built-in support for email digests, user preferences, and extensible delivery channels.
huynguyengl99/chanx
A batteries-included WebSocket framework for Django Channels, FastAPI, and ASGI-based applications.
codingjoe/django-crontask
Cron style scheduler for Django's task framework.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
26 Dec 2025 5:00pm GMT
24 Dec 2025
Django community aggregator: Community blog posts
From Bootcamp to Project Manager - Keanya Phelps
🔗 Links
- Behind the Curtain as a Conference Chair blog post
- DjangoCon US Conference Chair
- Opening Remarks and Closing Remarks at DjangoCon US
- PG Data 2026 Conference
- DjangoCon US: Call for Venue Proposals 2027-28
📦 Projects
📚 Books
🎥 YouTube
Sponsor
This episode was brought to you by Buttondown, the easiest way to start, send, and grow your email newsletter. New customers can save 50% off their first year with Buttondown using the coupon code DJANGO.
24 Dec 2025 6:00pm GMT
My 2026 year in review
As I prepared this post I realised I a lot more had happened this year than I thought, so without further a do here are the highlights I remember.
The new year started strong with me achieving my goal of writing a blog post every week day for a year. Since then I have scaled it back to approxmiately weekly, but there have been longer gaps over holidays or when worked was a bit too busy. It was a definite bonus to get 9 of my articles featured in Django News this year! The other content production I have been doing this year is a short podcast called "In Progress" which is a public-ish show about what I am working on week to week, I do plan to make this public at some point!
My big focus this year has been building an initial build for a startup I am co-founding. It's in the financial services space and I have a deadline for the end of January 2026. It's taken much longer than I would have liked, partly due to the table stakes features that were required, partly due to only being able to work part-time on it for most the year. Context switching between this and other client work/projects is a killer for productivity. However a win was moving to working mostly full-time from September and the pace certainly picked up then. The other contributing factor is LLM and agents finally clicking for me in my workflow. I don't think I would be as far in the build if it hadn't worked out for me.
On the topic of AI, I see it as a useful tool that has enabled me to ship some ideas and products much quicker as a solo developer than previously. django-deadcode is an example of this. Additionally plenty of features in the startup and some client projects. My general view is that the human work has shifted left towards the product understanding and those that understand that along with technical knowledge are benefitting right now. That said I'm not sure the current technological approach is sustainable so I am personally ready to switch back to the 'old' way or use a local model to continue using an LLM.
Django continued to be a large focus for my free time this year. I attended DjangoCon Europe for the second time and it was great to meet the community especially after interacting with folks online for so long over the last couple of years, there was a lot of fun to be had and I plucked up the courage to give a lighting talk about my 100 words goal and my startup sponsored the conference which was cool. Django Social's in Cambridge continued but at slightly slower pace mostly down to me forgetting to organise a date each month! In the online world, I now chair the Online Community Working Group and have become an admin on the Discord server. Finally I shipped a couple of packages, the previously mentioned django-deadcode was an AI experiment to see how much Claude could do before I even had to clone the repo locally (turns out a lot!). Second was finally pushing django-prodserver over the start line. I say start line as there is plenty of more work to do for this package and perhaps a merge into core Django?
The final piece of work life is I shipped the latest feature of Comfort Monitor Live, yay! However lost the 2 paying customers I had. I would like to round off the product at some point (1 more feature left), but it's currently on pause as my focus is on the items I have already mentioned in this post.
Finally there was a good amount of personal highlights, we upgrade to an electric cargo bike this year which has been lovely and I got a new single speed after the one I built was declared unsafe to ride after a service. Our holiday to the USA was some well needed rest along with fun on various camping trips (with family and with Cub Scouts). There were a few weddings this year and plenty of socials with friends old and new. On the subject of Cub Scouts it was great awarding several of the Cubs leaving with the highest award they can achieve, the Silver Chief Scout Award, it has taken us a few years to get organised, but it lovely to see them work hard and be rewarded for it.
So with the busy year almost done (just Christmas and 2 year old birthday to celebrate), I will see you all next year. Enjoy your Christmas and the celebration of our Saviour being born! (or however you celebrate!)
24 Dec 2025 6:00am GMT
19 Dec 2025
Django community aggregator: Community blog posts
Django News - New Django Software Foundation Board and Year-End Fundraiser - Dec 19th 2025
News
Hitting the Home Stretch: Help Us Reach the Django Software Foundation's Year-End Goal!
Django Software Foundation requests year-end donations to close a $300,000 fundraising goal, supporting an expanded Fellows program, security work, releases, and community events.
Introducing the 2026 DSF Board
Django Software Foundation announced the 2026 board and officers, welcomed the newly elected directors, thanked the outgoing members, and linked the board minutes and contact information.
DjangoCon US 2026 CFP is open!
DjangoCon US 2026 will take place September 14-18 in Chicago (talks September 14-16, sprints September 17-18), and the Call for Proposals is open now with a submission deadline of March 16, 2026 at 11:00 AM CDT.
PEP 8107 - 2026 Term Steering Council election
The results of the 2026 Python Steering Council election were published in PEP 8107, and the five winners are Pablo Galindo Salgado, Savannah Ostrowski, Barry Warsaw, Donghee Na, and Thomas Wouters. Congratulations to all of them on being elected to guide Python's development for the coming term.
Releases
Python 3.15.0 alpha 3
Python 3.15.0 alpha 3 is now available as an early developer preview, highlighting features like a new statistical sampling profiler, UTF-8 as the default encoding, a new PyBytesWriter C API, and improved error messages, with more changes planned before beta in May 2026.
Djangonaut Space News
Finding opportunities to contribute to Django
Djangonaut Space proposes creating a clear, welcoming "map" of the Django ecosystem to help newcomers discover meaningful ways to contribute, while encouraging projects to improve onboarding and contributor pathways.
Updates to Django
Today, "Updates to Django" is presented by Raffaella from Djangonaut Space! 🚀
Last week we had 15 pull requests merged into Django by 11 different contributors.
News in Django 6.1:
- The new
UUID4andUUID7database functions were added. GeneratedFieldnow supports stored columns (db_persistset toTrue) on Oracle 23ai/26ai (23.7+).
A special mention goes to the new contributors from last weeks: congratulations to Dmitry Chestnykh, Rida Zouga, Krishna Chaitanya, Hwayoung Cha 🚀, Νικόλαος-Διγενής Καραγιάννης, and Rim Choi 🚀 for having their first commits merged into Django - welcome on board!
Django Newsletter
Articles
ty: An extremely fast Python type checker and language server
ty is an extremely fast Python type checker and language server, written in Rust, and designed as an alternative to mypy, Pyright, and Pylance.
Dependency groups and uv run
Simon Willison explains a clean uv-based workflow using PEP 735 dependency groups, especially a dev group, to make Python projects instantly runnable and testable with uv run without manual virtual environment setup.
Rich text editors: How restrictive can we be?
django-prose-editor evolved from strict schemas to TextClass, NodeClass, and ClassLoom extensions to provide controlled, combinable CSS class styling while preserving safety.
My first win building with agents
Facundo Olano shares how he successfully shipped a minimal Django web app almost entirely with agentic coding, outlining a pragmatic, test-driven workflow that treats AI as a junior collaborator rather than a replacement for experienced Django judgment.
Your job is to deliver code you have proven to work
Simon Willison argues that in an era of AI-assisted development, a developer's real responsibility is not producing large amounts of code but delivering changes that are demonstrably proven to work through clear manual testing and solid automated tests.
Will Vincent's Year in Review (2025)
Will Vincent (Django News co-founder) reflects on 2025, covering his move to JetBrains as a Python Developer Advocate, conference talks and travel, major book and LearnDjango updates, a prolific year of blogging, podcasting, and newsletters, and his plans to focus more on video and Django 6.0 updates in 2026.
Kevin Renskers's 2025 in review
A reflective and productive year marked by personal upheaval, record-setting writing output, meaningful open source work, cautious AI adoption, and a growing emphasis on sustainability, focus, and choosing where limited time and energy truly matter.
Tutorials
🚀 How To Deploy Django 6 On Ubuntu VPS
Step-by-step production-ready guide showing how to deploy Django 6 on Ubuntu VPS using Gunicorn, Nginx, optional PostgreSQL, systemd, Certbot, and security hardening.
Sponsored Link 2
AI-Powered Django Development & Consulting
REVSYS specializes in integrating powerful AI technologies, including GPT-5, directly into your Django applications. We help bring modern, intelligent features to your project that boost user engagement and streamline content workflows.
Django Job Board
Here are this week's Django job highlights, spanning fully remote UK roles, US based security and platform work, and senior engineering positions, plus a quick reminder that Django News Jobs has rebranded as the Django Job Board at https://djangojobboard.com.
Founding Full-Stack Senior Engineer (UK ONLY) - Fully Remote at MyDataValue 🆕
Python/Django Senior Application Security Engineer at Energy Solutions
Python / Django Developer at Client of Foxley Talent
Staff Software Engineer at Bluebird Kids Health
Django Newsletter
Django Codebase
[Proposal] Scheduled daily GitHub workflow to run tests using Django's main branch #2391
Discussion and proposal to have djangoproject.com website run tests against Django main everyday.
Added "raw" argument to m2m_changed signals
Mariusz Felisiak fixed a 9-year old ticket allowing signals to skip receivers when loading fixtures (especially for m2m relations).
Projects
Django MailAuth just got a documentation refresh!
Django Mail Auth is a lightweight authentication backend for Django, that does not require users to remember passwords.
adamghill/django-new
Create new Django applications with pizazz. 🚀.
kennethlove/django-admin-action-hero
Easy admin action creation for Django.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
19 Dec 2025 5:00pm GMT
More adventures in building template components in Django
I discovered a new pattern in using one of the latest features from Django 6.0, template-partials. I probably need to give Claude some credit along with Tailwind Plus for the initial HTML. Earlier this week I was building out a modal pattern for the latest project I am building. You click a button, a modal pops up and loads a form via HTMX. Then submit the form and modal closes with the response triggering other HTMX updates on the page. I was building this out in tandem with Claude Code, with the starting point being a modal from Tailwind Plus which I thought only included the modal, but they also included the button to trigger the modal as well. Well the AI took this and ran with and essentially ended up with a Django template that looks like this:
{% partialdef trigger %}
<button hx-get...>...</button>
{% endpartialdef trigger %}
{% partialdef modal %}
<dialog>
<form>
...
</form>
</dialog>
{% endpartialdef modal %}
I don't think I would have ever thought to have included the button section as a partial in this context, but I like the results since both can be used with the include tag at different points and you have locality of behaviour if you want to update some aspect that affects both. I'm less likely to need to jump around to every button to add an attribute for example.
This got me thinking though, where else can partials fit in? Part of the magic with partials is the hash reference in the string reference to a template file. This means partials can be used in templatetags, earlier this year I wrote about using simple_block_tag in combination with get_template to produce a component like interface to build about a navigation. With partials I can merge the 3 small template files into a single template file with 3 partial templates. I think this is just the start for partials and template tags and I'm keen to explore their intersection even more in the coming weeks and months.
Finally the other area which Carlton recently hinted at on Mastodon is in the area of Form rendering. Django 4.X saw the refactoring of Form rendering into the FormRenderer class. This class allows the specification of snippet template files to customise how various form and form elements are rendered at a variety of levels from global down to individual forms. Again we can specify partials here instead of individual templates. I need to work on this a bit more, but the hope is a single file of partials that is something of a spritesheet of form components instead of jumping around multiple files. We can then use partials to deduplicate these templates.
Here is a quick example of my PartialsFormRenderer:
from django.forms.renderers import TemplatesSetting
class PartialsFormRenderer(TemplatesSetting):
form_template_name = "forms/form_snippet.html#form"
field_template_name = "forms/form_snippet.html#field"
```
I am excited for what comes next and how much we could achieve with Django features alone!
19 Dec 2025 6:00am GMT
17 Dec 2025
Django community aggregator: Community blog posts
Rich text editors: How restrictive can we be?
Rich text editors: How restrictive can we be?
How restrictive should a rich text editor be? It's a question I keep coming back to as I work on FeinCMS and Django-based content management systems.
I published the last blog post on django-prose-editor specifically in August 2025, Menu improvements in django-prose-editor. The most interesting part of the blog post was the short mention of the TextClass extension at the bottom which allows adding a predefined list of CSS classes to arbitrary spans of text.
In the meantime, I have spent a lot of time working on extensions that try to answer this question: the TextClass extension for adding CSS classes to inline text, and more recently the NodeClass extension for adding classes to nodes and marks. It's high time to write a post about it.
Rich Text editing philosophy
All of this convinced me that offering the user a rich text editor with too much capabilities is a really bad idea. The rich text editor in FeinCMS only has bold, italic, bullets, link and headlines activated (and the HTML code button, because that's sort of inevitable - sometimes the rich text editor messes up and you cannot fix it other than going directly into the HTML code. Plus, if someone really knows what they are doing, I'd still like to give them the power to shoot their own foot).
- Commit in the FeinCMS repository, August 2009, current version from django-content-editor design decisions
Should we let users shoot themselves in the foot?
Giving power users an HTML code button would have been somewhat fine if only the editors themselves were affected. Unfortunately, that was not the case.
As a team we have spent more time than we ever wanted debugging strange problems only to find out that the culprit was a blob of CSS or JavaScript inserted directly into an unsanitized rich text editor field. We saw everything from a few reasonable and well scoped lines of CSS to hundreds of KiBs of hotlinked JavaScript code that broke layouts, caused performance issues, and possibly even created security vulnerabilities.
We have one more case of Betteridge's law of headlines here.
The pendulum swings
The first version of django-prose-editor which replaced the venerable CKEditor 4 in our project was much more strict and reduced - no attributes, no classes, just a very short list of allowlisted HTML tags in the schema.
We quickly hit some snags. When users needed similar headings with different styles, we worked around it by using H2 and H3 - not semantic at all. I wasn't exactly involved in this decision; I just didn't want to rock the boat too much, since I was so happy that we were even able to use the more restricted editor at all in this project.
Everything was good for a while, but more and more use cases crept up until it was clear that something had to be done about it. First, the TextClass extension was introduced to allow adding classes to inline text, and later also the NodeClass extension mentioned above. This was a compromise: The customer wanted inline styles, we wanted as little customizability as possible without getting in the way.
That said, we obviously had to move a bit. After all, going back to a less strict editor or even offering a HTML blob injection would be worse. If we try to be too restrictive we will probably have to go back to allowing everything some way or the other, after all:
The more you tighten your grip, Tarkin, the more star systems will slip through your fingers.
- Princess Leia
Combining CSS classes
The last words are definitely not spoken just yet. As teased on Mastodon at the beginning of this month I am working on an even more flexible extension which unifies the NodeClass and TextClass extensions into a single ClassLoom extension.
The code is getting real world use now, but I'm not ready to integrate it yet into the official repository. However, you can use it if you want, it's 1:1 the version from a project repository. Get the ClassLoom extension here.
This extension also allows combining classes on a single element. If you have 5 colors and 3 text styles, you'd have to add 15 combinations if you were only able to apply a single class. Allowing combinations brings the number of classes down to manageable levels.
Conclusion
So, back to the original question: How restrictive can we be?
The journey from CKEditor 4's permissiveness through django-prose-editor's initial strictness to today's ClassLoom extension has been one of finding that balance. Each extension - TextClass, NodeClass, and now ClassLoom - represents a step toward controlled flexibility: giving content editors the styling options they need while keeping the content structured, maintainable, and safe.
17 Dec 2025 6:00pm GMT
12 Dec 2025
Django community aggregator: Community blog posts
Django News - DjangoCon Europe 2026 CFPs - Dec 12th 2025
News
DjangoCon Europe 2026: Call for Proposals
Submit talk proposals for DjangoCon Europe 2026 in Athens by February 8, 2026, to present technical or community-focused Django and Python topics.
Python Insider: Python 3.14.2 and 3.13.11 are now available!
Python 3.14.2 and 3.13.11 release expedited maintenance updates fixing regressions in multiprocessing, dataclasses, regex and insertdict plus security fixes including CVE-2025-12084.
Django Software Foundation
Django Code of Conduct Transparency Report 2025
The Django Software Foundation Code of Conduct working group published a 2025 transparency report detailing four reports, two suspensions, process changes, and new liaisons.
Online Community Working Group GitHub repo and project
Django Online Community Working Group launched a GitHub repository and project to centralise, track, and triage suggestions across Django's online platforms.
Django Fellow Reports
Fellow Report - Natalia
Big week. I issued security releases early in the week, and then the Django 6.0 final release right after. Getting both out the door smoothly took most of my focus, and it felt good to see them completed.
The flow of LLM driven contributions is becoming hard to ignore, across PRs, tickets, and even security reports. Skynet would be proud (?). This week was also heavy on meetings and coordinations.
Fellow Report - Jacob
An exciting week with Django 6.0 released and several security issues put to bed. Another highlight was merging Rim Choi's work making custom user models work better with fixture serialization.
Wagtail CMS News
Wagtail Wrapped 2025
Wagtail released four updates in 2025, including a 7.0 LTS aligned with Django, improved editor UX, AI package features, and autosave roadmap for 2026.
Up next on the roadmap
Wagtail 7.3 (Feb 2026) will add a StreamField block settings, content AI checks, model search enhancements, autosave draft, llms.txt docs to improve editor and developer workflows, and more!
Sponsored Link 1
Sleep tight with HackSoft and our Django services!
While you recharge, we keep your software running smoothly - secure, stable, and ready for tomorrow. We are HackSoft - your Django development partner, beyond code. Learn more!
Articles
Introducing Django RAPID Architecture: Patterns for Real‑World Django Codebases
A post on the new online and free Django RAPID Architecture guide.
Build a RAG App With Django MongoDB Backend in 30 minutes
A fast, step-by-step guide to building a holiday-movie RAG search app in 30 minutes using Django, MongoDB, Voyage AI embeddings, and LangChain.
Deprecations via warnings don't work for Python libraries
DeprecationWarning is ignored by default, so Python libraries cannot rely on it for API breakage notices and should use visible warnings or stricter versioning.
Django: implement HTTP basic authentication
Implement HTTP Basic authentication in Django by decoding Basic Authorization headers, securely validating credentials with secrets.compare_digest, and returning 401 with WWW authenticate header.
The Autobiography of a Python Object
Explains Python object lifecycle, special methods like __repr__ and __iter__, attribute handling, and reference counting leading to garbage collection, with illustrative examples.
Events
PyCon US 2026 - Registration, Hotels, Travel Grants & More!
PyCon US 2026 registration is open for May 13, 2026 to May 19, 2026 in Long Beach, offering early bird rates, housing and travel grants.
Tutorials
How to send email with Django: Complete SMTP guide
Guide explains configuring Django's SMTP backend, using send_mail, EmailMessage, and send_mass_mail for plain, HTML, attachment, and bulk email sending while securing credentials via environment variables.
Podcasts
Django 6.0 - Natalia Bidart
Natalia is a Django Fellow and the release manager for the just-released 6.0 version. We talk about the new release, major features including template partials that Carlton helped usher in, queues, CSP support, modern email API, and the current work on Django 6.1.
Django Job Board
Django News Jobs is now the Django Job Board and has a new domain: https://djangojobboard.com
New Django and Python roles this week span application security, backend development, and staff-level engineering.
Python/Django Senior Application Security Engineer at Energy Solutions
Python / Django Developer at Client of Foxley Talent
Staff Software Engineer at Bluebird Kids Health
Django Newsletter
Projects
FarhanAliRaza/django-repl
Run Django in the browser.
codingjoe/django-crontask: Cron style scheduler for Django's task framework
Cron style scheduler for Django's task framework. Contribute to codingjoe/django-crontask development by creating an account on GitHub.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
12 Dec 2025 5:00pm GMT
11 Dec 2025
Django community aggregator: Community blog posts
Django 6.0 - Natalia Bidart
- Django 6.0 Released blog post and release notes
- Deprecations Don't Work for Python Libraries
- Django Forum - Should We Adjust Django's Versioning?
- django-repl and django-bolt
- Template Fragments essay on HTMX.org
- django-tasks
- What's New in Django 6.0 by Adam Johnson
- DjangoCon Europe 2024 | Empowering Django with Background Workers
Sponsor
This episode was brought to you by HackSoft, your development partner beyond code. From custom software development to consulting, team augmentation, or opening an office in Bulgaria, they're ready to take your Django project to the next level!
11 Dec 2025 11:05pm GMT
10 Dec 2025
Django community aggregator: Community blog posts
Hello world!
Welcome to WordPress. This is your first post. Edit or delete it, then start writing!
10 Dec 2025 5:37am GMT
08 Dec 2025
Django community aggregator: Community blog posts
Django: implement HTTP basic authentication
Previously, we covered bearer authentication within HTTP's general authentication framework. In this post, we'll implement basic authentication, where the client provides a username and password.
To recap, HTTP's general authentication framework defines a general scheme for authentication:
- Clients may provide an
authorizationrequest header that contains a credential. - Servers validate the header and respond with either the requested resource or a 401 (Unauthorized) status code that includes a
www-authenticateresponse header advertising what authentication schemes are supported.
Basic authentication is an authentication scheme within the framework that browsers natively support. When accessing a page protected with basic authentication, browsers show a login prompt to the user, like this one in Firefox:

After the user enters their credentials, the browser sends a new request with the authorization header set to the string Basic <credentials>, where <credentials> is a base64-encoded string of the form <username>:<password>. The server can then validate the credentials and respond accordingly.
Basic authentication is not the best user experience, as the browser login dialog cannot be styled and password managers cannot autofill it. It also requires some security considerations, as the credentials are sent with every request to the protected resource, increasing the risk of exposure, but if you use HTTPS, as basically required for the modern web, this risk is somewhat mitigated. Despite these downsides, basic authentication is convenient for simple use cases, like temporarily password-protecting a work-in-progress page, as it's fast to implement without any HTML, CSS, or JavaScript. And sometimes it's just plain required to integrate with a legacy system.
Django doesn't provide built-in basic authentication, but it takes minimal code to implement it yourself. Django REST Framework does provide BasicAuthentication, but it's not a particularly convenient authentication method for APIs.
Here is a complete example of how to implement Basic authentication for a Django view:
import base64
import os
import secrets
from http import HTTPStatus
from django.shortcuts import render
USERNAME = os.environ.get("SECRET_STUFF_USERNAME", "")
PASSWORD = os.environ.get("SECRET_STUFF_PASSWORD", "")
def secret_stuff(request):
authorization = request.headers.get("authorization", "")
if not USERNAME or not PASSWORD:
# Unconfigured, deny all access
return _unauthorized(request)
if not authorization.startswith("Basic "):
return _unauthorized(request)
authorization = authorization.removeprefix("Basic ")
try:
credentials = base64.b64decode(authorization).decode("utf-8")
username, password = credentials.split(":", 1)
except (ValueError, UnicodeDecodeError):
return _unauthorized(request)
username_matches = secrets.compare_digest(username, SECRET_STUFF_USERNAME)
password_matches = secrets.compare_digest(password, SECRET_STUFF_PASSWORD)
if not username_matches or not password_matches:
return _unauthorized(request)
return render("secret_stuff.html", request)
def _unauthorized(request):
response = render(
request,
"unauthorized.html",
status=HTTPStatus.UNAUTHORIZED,
)
response.headers["www-authenticate"] = 'Basic realm="Secret area!"'
return response
For this example, there's a single valid username-password pair, provided through environment variables. If those environment variables are not set, the view denies all access, otherwise it checks that the authorization header is present and correctly formatted. Basic authentication credentials are base64-encoded strings of the form username:password, so the view decodes and splits the credentials accordingly, then compares them with the expected values using secrets.compare_digest() to avoid timing attacks.
If any step of the validation fails, the view responds with a 401 Unauthorized response, with the www-authenticate header advertising the Basic scheme. This header prompts browsers to show the login dialog. If the credentials are valid, the view renders the protected content.
To test this view, we can use Django's test client:
from base64 import b64encode
from http import HTTPStatus
from unittest import mock
from django.test import SimpleTestCase
from example import views
@mock.patch.multiple(
views,
SECRET_STUFF_USERNAME="admin",
SECRET_STUFF_PASSWORD="hunter2",
)
class SecretStuffTests(SimpleTestCase):
def test_unauthorized_no_header(self):
response = self.client.get("/secret-stuff/")
assert response.status_code == HTTPStatus.UNAUTHORIZED
assert "<h1>Unauthorized</h1>" in response.text
assert response.headers["www-authenticate"] == 'Basic realm="Secret area!"'
def test_unauthorized_unconfigured(self):
with mock.patch.multiple(
views, SECRET_STUFF_USERNAME="", SECRET_STUFF_PASSWORD=""
):
credentials = b64encode(b"admin:hunter2").decode()
response = self.client.get(
"/secret-stuff/",
headers={"authorization": f"Basic {credentials}"},
)
assert response.status_code == HTTPStatus.UNAUTHORIZED
assert "<h1>Unauthorized</h1>" in response.text
assert response.headers["www-authenticate"] == 'Basic realm="Secret area!"'
def test_unauthorized_wrong_authorization_type(self):
response = self.client.get(
"/secret-stuff/",
headers={"authorization": "Bearer sometoken"},
)
assert response.status_code == HTTPStatus.UNAUTHORIZED
assert "<h1>Unauthorized</h1>" in response.text
assert response.headers["www-authenticate"] == 'Basic realm="Secret area!"'
def test_unauthorized_malformed_credentials(self):
malformed_credentials = b64encode(b"malformedcredentials").decode()
response = self.client.get(
"/secret-stuff/",
headers={"authorization": f"Basic {malformed_credentials}"},
)
assert response.status_code == HTTPStatus.UNAUTHORIZED
assert "<h1>Unauthorized</h1>" in response.text
def test_unauthorized_wrong_username(self):
wrong_credentials = b64encode(b"wrong:hunter2").decode()
response = self.client.get(
"/secret-stuff/",
headers={"authorization": f"Basic {wrong_credentials}"},
)
assert response.status_code == HTTPStatus.UNAUTHORIZED
assert "<h1>Unauthorized</h1>" in response.text
assert response.headers["www-authenticate"] == 'Basic realm="Secret area!"'
def test_unauthorized_wrong_password(self):
wrong_credentials = b64encode(b"admin:wrongpassword").decode()
response = self.client.get(
"/secret-stuff/",
headers={"authorization": f"Basic {wrong_credentials}"},
)
assert response.status_code == HTTPStatus.UNAUTHORIZED
assert "<h1>Unauthorized</h1>" in response.text
def test_authorized_access(self):
credentials = b64encode(b"admin:hunter2").decode()
response = self.client.get(
"/secret-stuff/",
headers={"authorization": f"Basic {credentials}"},
)
assert response.status_code == HTTPStatus.OK
assert "<h1>🤫 Secret stuff</h1>" in response.text
These tests cover all paths through the code, giving 100% coverage.
mock.patch.multiple() is particularly neat for setting the expected username and password during the tests, overriding any environment variable configuration.
Extract a decorator to curtail constant copying
If you have multiple views that need authentication, don't copy authentication code between them. Instead, extract the authentication logic into a view decorator, like:
import base64
import functools
import os
import secrets
from http import HTTPStatus
from django.shortcuts import render
SECRET_STUFF_USERNAME = os.environ.get("SECRET_STUFF_USERNAME", "")
SECRET_STUFF_PASSWORD = os.environ.get("SECRET_STUFF_PASSWORD", "")
def basic_auth(view_func):
@functools.wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
authorization = request.headers.get("authorization", "")
if not SECRET_STUFF_USERNAME or not SECRET_STUFF_PASSWORD:
return _unauthorized(request)
if not authorization.startswith("Basic "):
return _unauthorized(request)
authorization = authorization.removeprefix("Basic ")
try:
credentials = base64.b64decode(authorization).decode("utf-8")
username, password = credentials.split(":", 1)
except (ValueError, UnicodeDecodeError):
return _unauthorized(request)
username_matches = secrets.compare_digest(username, SECRET_STUFF_USERNAME)
password_matches = secrets.compare_digest(password, SECRET_STUFF_PASSWORD)
if not username_matches or not password_matches:
return _unauthorized(request)
return view_func(request, *args, **kwargs)
return _wrapped_view
def _unauthorized(request):
response = render(
request,
"unauthorized.html",
status=HTTPStatus.UNAUTHORIZED,
)
response.headers["www-authenticate"] = 'Basic realm="Secret area!"'
return response
@basic_auth
def secret_recommendation(request):
return render("secret_recommendation.html", request)
@basic_auth
def secret_info(request):
return render("secret_info.html", request)
Extensions
It may be sufficient to support just a single hardcoded username and password pair, as above, for example for a demo site that only a few trusted users will access. But in more complex scenarios, you may want to support multiple users and passwords, Django's user model integration, rate limiting, and so on. You can certainly extend the above code to support those features, though at some point it will probably make sense to switch to a classic login form instead, typically through Django's authentication framework.
08 Dec 2025 6:00am GMT
05 Dec 2025
Django community aggregator: Community blog posts
Weeknotes (2025 week 49)
Weeknotes (2025 week 49)
I seem to be publishing weeknotes monthly, so I'm now thinking about renaming the category :-)
Mosparo
I have started using a self-hosted mosparo instance for my captcha needs. It's nicer than Google reCAPTCHA. Also, not sending data to Google and not training AI models on traffic signs feels better.
Fixes for the YouTube 153 error
Simon Willison published a nice writeup about YouTube embeds failing with a 153 error. We have also encountered this problem in the wild and fixed the feincms3 embedding code to also set the required referrerpolicy attribute.
Updated packages since 2025-11-04
- django-sitemaps 2.0.2: Uploaded a new release which includes a wheel build. Rebuilding the wheel all the time when creating new container images was getting annoying. The code itself is unchanged.
- django-prune-uploads 0.3.1: The package now supports pruning a storage backed by django-s3-storage efficiently. I have also looked at django-prune-media but since the package uses the storage API instead of enumerating files using boto3 directly it's unusably slow for my use case.
- feincms3-forms 0.6: Much better docs and a new way to reference individual form fields in custom templates.
- django-json-schema-editor 0.11: Switched from JSON paths to
jmespathinstances. Made the JSON model instance reference support easier and more fun to use. Added new ways of customizing the generated proxy model for individual JSON plugin instances. - form-designer 0.27.1: Added support for the mosparo captcha to the default list of field types.
- asgi-plausible 0.1.1: No code change really, just added required dependencies to the package metadata.
- django-tree-queries 0.23: The package now ships a
OrderableTreeNodebase model which you can use when you want to order siblings manually. feincms3 already uses this base model for its pages model. - feincms3-data 0.10: This is quite a big one. I discovered issues with the way
save_as_new(to copy data) anddelete_missinginteracted. First the code was cleaned up to delete less data, and then to delete enough data. I'm now somewhat confident that the code does what it should again. - django-prose-editor 0.22.3: Started returning an empty string for an empty document instead of
<p></p>also when using the frontend integration; previously, this transformation was only implemented when using at least the form if not the model field. Also,<ol>tags now have adata-typeattribute since Chrome cannot case-sensitively match e.g.type="a"vstype="A"for lowercase or uppercase letters. I previously only tested the code in Firefox and there it worked nicely.
05 Dec 2025 6:00pm GMT

