Django community: RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Production-ready cache-busting for Django and Tailwind CSS
I’m a big fan of the django-tailwind-cli package. It makes integrating Tailwind CSS into a Django project incredibly simple. By managing the Tailwind watcher process for you, it streamlines development, especially when paired with django-browser-reload for live updates. It’s a fantastic developer experience. However, when I first deployed a project using this setup, I ran into a classic problem: caching. You see, django-tailwind-cli creates a single tailwind.css file that you load in your base template. In production, browsers and CDNs will aggressively cache this file to improve performance. This is normally a good thing! But when you deploy an update, like adding a new Tailwind class to a template, your users might not see the changes. Their browser will continue to serve the old, cached tailwind.css file, leading to broken or outdated styling. Luckily, Django has a built-in cache-busting mechanism in the form of ManifestStaticFilesStorage. But, there’s one important caveat: you can’t use this class directly. The Tailwind build process relies on a source file (typically css/source.css) that contains this line: @import "tailwindcss"; When collectstatic runs, ManifestStaticFilesStorage tries to be helpful and process this file, too. It attempts to find and hash source.css, and it also attempts to hash the … -
Building a Multi-tenant App with Django
This tutorial looks at how to implement multi-tenancy in Django. -
Native connection pooling in Django 5 with PostgreSQL
Enabling native connection pooling in Django 5 gives me a 5.4x speedup. -
Django: Introducing inline-snapshot-django
I recently released a new package called inline-snapshot-django. It’s a tool for snapshot testing SQL queries in Django projects, described shortly. Snapshot testing and inline-snapshot inline-snapshot-django builds on top of the excellent inline-snapshot, a nifty snapshot testing library. Snapshot testing is a type of testing that compares a result against a previously captured “snapshot” value. It can enable you to write tests quickly and assert on many details that you'd otherwise miss. Snapshot testing is quite popular in other languages, such as JavaScript, but it has been underused in Python. This may be due to a lack of good tools to help automate snapshot management. inline-snapshot provides nice workflows tied into pytest, so I hope it will popularize the technique among Python and Django developers. The inline-snapshot developer, Frank Hoffmann, is working intensely on it, and he provides some extra tools and features for his GitHub sponsors. inline-snapshot-django I created inline-snapshot-django to provide an advanced yet easier-to-use alternative to Django’s assertNumQueries(). While assertNumQueries() is handy, it is a rather blunt tool that leaves you in the dark when debugging failures. For example, say you encountered this test: from django.test import TestCase class IndexTests(TestCase): def test_success(self): with self.assertNumQueries(1): response = self.client.get("/") … -
Django News - Python 3.14.0 beta 3 - Jun 20th 2025
News DSF member of the month - Elena Williams Elena Williams, Django community stalwart and DSF Code of Conduct WG member, reflects on her contributions, favorite Django features, and community leadership. djangoproject.com International Travel to DjangoCon US 2025 Are you attending DjangoCon US 2025 in Chicago, Illinois, but you are not from US and need some travel information? Here are some things to consider when planning your trip. djangocon.us Python 3.14.0 beta 3 is released! Python 3.14.0 beta 3 adds deferred annotation evaluation, template string literals, multiple interpreters, zstd compression module, free-threaded support and other core improvements, ready for testing. blogspot.com 2025 PSF Board Election Schedule PSF defines 2025 board election schedule with nomination, voter affirmation, voting dates, membership eligibility, and candidate resources for the Python community. blogspot.com Updates to Django Today 'Updates to Django' is presented by Abigail Afi Gbadago from the DSF Board and Djangonaut Space!🚀 Last week we had 18 pull requests merged into Django by 15 different contributors - including 6 first-time contributors! Congratulations to Viliam Mihálik, Sulove Bista, ruvilonix, Jericho Serrano, nakanoh and Jeff Cho for having their first commits merged into Django - welcome on board!🎊 This week’s Django highlights 💫 A follow-up to … -
Avoiding Timezone Traps: Correctly Extracting Date/Time Subfields in Django with PostgreSQL
Working with timezones can sometimes lead to confusing results, especially when combining Django's ORM, raw SQL for performance (like in PostgreSQL materialized views), and specific timezone requirements. I recently had an issue while aggregating traffic stop data by year, where all yearly calculations needed to reflect the 'America/New_York' (EST/EDT) timezone, even though our original data contained timestamp with time zone fields. We were using django-pgviews-redux to manage materialized views, and I mistakenly attempted to apply timezone logic to a date field that had no time or timezone information. The core issue stemmed from a misunderstanding of how PostgreSQL handles EXTRACT operations on date types when combined with AT TIME ZONE, especially within a Django environment that defaults database connections to UTC. PostgreSQL's Handling of Timestamps and Timezones PostgreSQL's timestamp with time zone (often abbreviated as timestamptz) type is a common database type for storing date and time information. As per the PostgreSQL documentation: For timestamp with time zone values, an input string that includes an explicit time zone will be converted to UTC (Universal Coordinated Time) using the appropriate offset for that time zone. When you query a timestamptz column, PostgreSQL converts the stored UTC value back to the current … -
Django News - New Django Fellow Position! - Jun 13th 2025
News DSF calls for applicants for a Django Fellow DSF invites experienced Django developers to apply for a new Django Fellow position focused on framework maintenance, mentoring, and security oversight. djangoproject.com Django bugfix releases issued: 5.2.3, 5.1.11, and 4.2.23 Django issues bugfix releases for 5.2.3, 5.1.11, and 4.2.23 to finalize mitigation for potential log injection using safer logging practices. djangoproject.com Python Release Python 3.13.5 Python 3.13.5 resolves critical bugs in extension building and generator expressions, complementing Python 3.13's experimental free-threaded mode and JIT for improved performance. python.org Updates to Django Hello there 👋 Today 'Updates to Django' is presented by Raffaella from Djangonaut Space! 🚀 Last week we had 11 pull requests merged into Django by 10 different contributors - including 2 first-time contributors! Congratulations to myoungjinGo and Blayze for having their first commits merged into Django - welcome on board! Fixes from last week include: A log injection possibility: the remaining response logging is migrated to django.utils.log.log_response(), which safely escapes arguments such as the request path to prevent unsafe log output (CVE-2025-48432). This is released within 5.2.3, 5.1.11, and 4.2.23. An issue where bulk_create() would raise an IntegrityError due to null values in the _order column when used with … -
iSAQB meetup: software architecture decision making in practice
I attended a meetup of the Dutch iSAQB community in Utrecht (NL). The location was in the old industrial buildings of the former werkspoor train manufacturer, something I personally like :-) (At least three people asked me during dinner whether there were any Dutch python meetups, so I'll post the three active ones that I know of here for ease of finding them: Utrecht, Leiden and Amsterdam. And don't forget the two one-day conferences, PyGrunn (Groningen) and pycon NL (Utrecht).) Making significant software architecture decisions - Bert Jan Schrijver Software architecture. What is software? Algorithms, code-that-works, the-part-you-cannot-kick. And what is software architecture? The part that is expensive to change, the structure of the system, best practices. The decisions that are important and hard and expensive to change. Software architecture is about making decisions. Decisions that hurt when you get them wrong. There are bad reasons for architecture decisions: We've always done it like this. We don't want to depend on XYZ. We need to be future-proof. (You often get elaborate complex systems with this reasoning. Isn't a simple solution more changeable and future-proof?) Because the product owner wants it. Because the architect wants it. (If the architect wants something without … -
Make Django show dates and times in the visitor’s local timezone
When you’re building a web app with Django, handling timezones is a common hurdle. You’re likely storing timestamps in your database in UTC—which is best practice—but your users are scattered across the globe. Showing them a UTC timestamp for when they left a comment isn’t very friendly. They want to see it in their own, local time. Let’s start with a typical scenario. You have a Comment model that stores when a comment was added: models.py class Comment(models.Model): post = models.ForeignKey(Post, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE) comment = models.TextField() added = models.DateTimeField(auto_now_add=True) In your Django settings, you’ve correctly set TIME_ZONE = "UTC". When you render these comments in a template, you’ll find the problem right away: post.html {% for comment in post.comment_set.all %} <div> <h3>From {{ comment.user.name }} on {{ comment.added }}</h3> <p>{{ comment.comment }}</p> </div> {% endfor %} The output for {{ comment.added }} will be in UTC, not the visitor’s local time. Let’s fix that. The Server-Side Fix: A Timezone Middleware The most robust way to solve this is on the server. If Django knows the user’s timezone, it can automatically convert all datetime objects during rendering. The plan is simple: Use JavaScript to get the visitor’s timezone … -
Beyond htmx: building modern Django apps with Alpine AJAX
I’ve recently been rethinking how I build web applications. For the past few years my default has been a Django backend serving a JSON API to a frontend built with SvelteKit. And I am not alone; many (if not most) sites now use a complex JavaScript frontend and a JSON API. This pattern, the Single-Page Application (SPA), brought us amazing user experiences, but it also brought a mountain of complexity: state management, API versioning, client-side routing, duplicate form validation, build tools, and the endless churn of the JavaScript ecosystem. And then I came across htmx, which promises to enhance HTML to the point where your old-fashioned Multi-Page Application (MPA) feels modern, without having to write a single line of JavaScript. We can have the smooth, modern UX of a SPA but with the simplicity and robustness of traditional, server-rendered Django applications. This article is about why I believe this “Hypermedia-Driven Application” approach is a better fit for many Django projects than a full-blown SPA, and why I ultimately chose Alpine AJAX over the more popular htmx. Returning to true REST and hypermedia To understand why this “new” approach feels so simple, we need to look back at the original principles … -
Migrating Python & Django Projects to uv
I recently migrated a legacy project that used requirements files to uv. I undertook the project in hopes of streamlining the setup process and to help to ensure that the versions of packages installed locally, in CI/CD, and in production are all consistent. uv manages everything about your Python environment, so I found it's best to start with uv's approach and integrate other tools as needed. Local development To migrate a legacy project to uv, I followed these steps. First, I added a project definition to our project's pyproject.toml: [project] name = "my-product" version = "1.2.3" description = "Our amazing product." readme = "README.md" requires-python = "~=3.12" dependencies = [] Then, I moved the requirements from our pre-existing requirements files to the project dependencies and removed the old files: uv add -r requirements/base.txt uv add -r requirements/dev.txt --group dev uv add -r requirements/deploy.txt --group deploy git rm requirements/*.txt This adds the base requirements to the dependencies list in pyproject.toml, and the dev and deploy requirements to the dev and deploy groups, respectively. Next, I installed and pinned a Python version, and synced the dependencies: uv python install 3.12 uv python pin 3.12 uv sync This installs a Python 3.12 interpreter, … -
PHP Web Frameworks - Roman Pronskiy
Roman’s personal site, GitHub, and YouTube channel The PHP FoundationThe New Life of PHP – The PHP Foundation PHP Annotated Newsletter PHP 3 to 8: The Evolution of a Codebase PHPStorm 2025.1 SponsorThis 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. -
Django News - Django security releases issued: 5.2.2, 5.1.10, and 4.2.22 - Jun 6th 2025
News Django security releases issued: 5.2.2, 5.1.10, and 4.2.22 Django issues security patches in 5.2.2, 5.1.10, and 4.2.22, resolving a moderate severity log injection vulnerability in internal logging via unescaped request.path. djangoproject.com Python 3.13.4, 3.12.11, 3.11.13, 3.10.18 and 3.9.23 are now available! The Python 3.13.4 release includes over 300 bug fixes, and every version of Python has received three security updates. python.org django-unicorn - Request for maintainer(s) Django-unicorn seeks new maintainers to help evolve its interactive component library, address complexity, improve features, and support continued development within Django projects. dev.to Python Packaging Ecosystem Survey Participate in Anaconda’s survey to share your Python packaging experiences and resource preferences, helping guide future improvements in the packaging ecosystem. surveymonkey.com Updates to Django Today 'Updates to Django' is presented by Pradhvan from the Djangonaut Space! 🚀 Last week we had 3 pull requests merged into Django by 3 different contributors - including 1 first-time contributor! Congratulations to Jason Judkins for having their first commit merged into Django - welcome on board! 🥳 This week’s Django highlight: 🦄 Jason, updated the package name in Django's reusable apps tutorial to follow PEP 625 standards. Django Newsletter Wagtail CMS Closing the gap: strict CSP in the Django … -
Preserving referential integrity with JSON fields and Django
Preserving referential integrity with JSON fields and Django Motivation The great thing about using feincms3 and django-content-editor is that CMS plugins are Django models – if using them you immediately have access to the power of Django’s ORM and Django’s administration interface. However, using one model per content type can be limiting on larger sites. Because of this we like using JSON plugins with schemas for more fringe use cases or for places where we have richer data but do not want to write a separate Django app for it. This works well as long as you only work with text, numbers etc. but gets a bit ugly once you start referencing Django models because you never know if those objects are still around when actually using the data stored in those JSON fields. Django has a nice on_delete=models.PROTECT feature, but that of course only works when using real models. So, let’s bridge this gap and allow using foreign key protection with data stored in JSON fields! Models First, you have to start using the django-json-schema-editor and specifically its JSONField instead of the standard Django JSONField. The most important difference between those two is that the schema editor’s field wants … -
An easy way to use different serializers for different actions and request methods in Django REST Framework
Imagine a simple Django REST Framework serializer and view like this: from rest_framework import serializers from rest_framework import viewsets from .models import Post class PostSerializer(serializers.ModelSerializer): class Meta: model = Post fields = "__all__" class PostViewSet(viewsets.ModelViewSet): serializer_class = PostSerializer def get_queryset(self): return Post.objects.all() The PostSerializer class is used for everything: the list of posts, retrieving a single post, the payload when creating or updating a post, and the response when creating or updating a post. I find that this is often not what I want; for example I often want a simple version of the model to be returned in the list endpoint (/posts/), while the full model is returned in the retrieve endpoint (/posts/{post_id}/). And I also often want that the input serializer is different from the output serializer, when creating or updating something (especially when using DRF’s built-in Browsable API, because it includes all the read-only fields in the example input payload, causing confusion). Using different serializers in the list and retrieve endpoints isn’t too hard: class PostViewSet(viewsets.ModelViewSet): def get_serializer_class(self): if self.action == "list": return PostListSerializer return PostDetailSerializer But when you also want to use different input and output serializers when creating and updating models, then you need to … -
Changing Directions
Two announcements: (1) I’m leaving the tech industry. Hopefully “for good”; if not, at least “for now”. (2) As such, the content on this blog is going to shift, perhaps dramatically. I’m going to be writing about a broader range of topics that interest me (projects around my hobby farm, wilderness trips, emergency medicine) – more writing for me, less writing for some imagined audience. (I’ll probably still end up writing about some of the same topics as I’ve been covering since 2020, just less often.) I’m writing this post mostly to give myself permission to make that change, and to give readers the opportunity to unsubscribe/unfollow if they’re not interested. -
Django News - DjangoCon US Early Bird Tickets - May 30th 2025
News Python Release Python 3.14.0b2 Python 3.14.0b2 beta introduces deferred type annotations, t-string templating, improved error messages, and remote debugging support that may influence Django project testing. python.org Updates to Django Fixed #35629 -- Added support for async database connections and cursors. Enhances Django's ORM with asynchronous database connections and low-level cursor support for executing raw SQL queries, improving async performance and transaction management. github.com Wagtail CMS What’s new in Wagtail - May 2025 highlights May 2025 Wagtail update for Django developers details LTS release enhancements with autosave progress, dynamic StreamField previews, improved accessibility and active community contributions. wagtail.org Sponsored Link 1 Open a Django office in Bulgaria with HackSoft! Looking to expand your operations? We offer end-to-end support in setting up your Django development office. Learn more! hacksoft.io Articles Faster Python Docker Builds Optimize Django and Python Docker builds by caching dependencies, using uv pip, and multi-stage builds to drastically reduce fresh build and rebuild times. revsys.com How I'm bundling frontend assets using Django and rspack these days Using rspack for frontend asset bundling in Django enables efficient hot module reloading, content-based cache busting, and streamlined production builds via reusable configuration snippets. 406.ch Another Great PyCon PyCon US 2025 … -
Django Deployments in 2025 - Eric Matthes
Python Crash Course, 3rd Editiondjango-simple-deployMostly Python NewsletterDjango From First Principles SeriesDJP: A Plugin System for Djangodsd-vpsdjango-productionSponsorThis 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. -
DjangoCon Europe 2025 Highlights
Three Cakti recently attended DjangoCon Europe 2025 in Dublin and it was a wonderful experience! It was great to see and chat with various Django community members we usually only see once or twice a year. Beyond that, we were most impressed by the consistently high quality of the talks throughout all three days of the conference. It was a pleasure to listen to so many excellent presentations, including the lightning talks at the end of each day. Here are some of our favorite talks. Karen Tracey It is hard to pick out a single favorite, so I am going to mention a few: Tim Bell from Kraken Technologies Australia gave a talk on Converting integer fields to bigint using Django migrations at scale, followed up by a lightning talk a couple of days later that revealed how the real life production situation which was the inspiration for the talk was quite a near thing and required some daring creativity to sidestep disaster. I hope never to be in a similar situation but I do find talks on solving challenging production problems very enjoyable. In a similar vein, Mia Bajić presented a keynote on The Most Bizarre Software Bugs in … -
How I'm bundling frontend assets using Django and rspack these days
How I’m bundling frontend assets using Django and rspack these days I last wrote about configuring Django with bundlers in 2018: Our approach to configuring Django, Webpack and ManifestStaticFilesStorage. An update has been a long time coming. I wanted to write this down for a while already, but each time I started explaining how configuring rspack is actually nice I look at the files we’re using and switch to writing about something else. This time I managed to get through – it’s not that bad, I promise. This is quite a long post. A project where all of this can be seen in action is Traduire, a platform for translating gettext catalogs. I announced it on the Django forum. Our requirements The requirements were still basically the same: Hot module reloading during development A process which produces hashed filenames depending on their content so that we can use far-future expiry headers to cache assets in browsers While running Node.js in development is fine we do not want Node.js on the server (in the general case) We still want transpiling and bundling for now We have old projects using SASS. These days we’re only using PostCSS (especially autoprefixer and maybe postcss-nesting. … -
Django News - Django Sprints on the Med? - May 23rd 2025
News Django sprints? On the Med? A new initiative from Carlton Gibson and Paolo Melchiorre to organize three-day development sprints to get together and work on Django. buttondown.com DjangoCon US early-bird tickets are going fast! DjangoCon US 2025 early-bird tickets are now available at discounted rates through May for individuals and corporate attendees in Chicago. djangocon.us Django Commons launched a website! Django Commons launched their new website. django-commons.org Django Fellow Report Django Fellow Report - Natalia Bidart 3 triaged tickets, 8 reviewed, 1 authored, plus a lot of misc! djangoproject.com Django Fellow Report - Sarah Boyce 18 tickets triaged, 19 reviewed, plus misc! djangoproject.com Django Software Foundation Our Google Summer of Code 2025 contributors Google Summer of Code 2025 contributors will implement keyboard shortcuts and command palette in Django Admin, integrate template partials into core and automate contribution workflows. djangoproject.com Updates to Django Today 'Updates to Django' is presented by Pradhvan from the Djangonaut Space!🚀 Last week we had 20 pull requests merged into Django by 16 different contributors - including 4 first-time contributors! Congratulations to savanto, Kashemir001, Pablo Bengoechea and Samuel Cormier-Iijima for having their first commits merged into Django - welcome on board! 🎉 This week’s Django highlights … -
Django, JavaScript modules and importmaps
How I’m using Django, JavaScript modules and importmaps together I have been spending a lot of time in the last few months working on django-prose-editor. First I’ve rebuilt the editor on top of Tiptap because I wanted a framework for extending the underlying ProseMirror and didn’t want to reinvent this particular wheel. While doing that work I noticed that using JavaScript modules in the browser would be really nice, but Django’s ManifestStaticFilesStorage doesn’t yet support rewriting import statement in modules out-of-the-box without opting into the experimental support accessible through subclassing the storage. A better way to use JavaScript modules with the cache busting offered by ManifestStaticFilesStorage would be importmaps. Motivation Developing Django applications that include JavaScript has always been challenging when it comes to properly distributing, loading, and versioning those assets. The traditional approach using Django’s forms.Media works well for simple use cases, but falls short when dealing with modern JavaScript modules. The ability to ship reusable JavaScript utilities in third-party Django apps has been a pain point for years. Often developers resort to workarounds like bundling all JS into a single file, using jQuery-style global variables, or requiring complex build processes for consumers of their apps. Importmaps offer a … -
Django is not a framework but a Protocol
This has been a concept that has been brewing in my mind for the last couple of months. It's been mostly inspired by my desire to see a prodserver (final name TBC) in Django Core alongside runserver and why it sitting happily as third-party package would, to me, not be a sufficient solution. As part of some research on potential names for commands I dug into the django-tasks DEP to understand how the worker would be started. My findings found that it will be currently left to future iterations with the current solution delegated to the implementation (read a third-party package). Additionally Carlton's talk at DjangoCon Europe this year teased at the idea of modularization, how can we break up Django for some aspects to ship faster. I too have toyed this with in the past in regard to the contrib module. Carlton has also written about Django having a grain, a natural way of working, to the extent that I would say we have Djangonic?! code in addition to code being Pythonic. Finally to reference the Zen of Python: There should be one-- and preferably only one --obvious way to do it. This has become harder to see as … -
Weeknotes (2025 week 21)
Weeknotes (2025 week 21) I have missed two co-writing sessions and didn’t manage to post much outside of that, but let’s get things back on track. django-prose-editor 0.12 The last weeknotes entry contains more details about the work of really connecting Tiptap extensions with server-side sanitization. 0.12 includes many improvements and bugfixes which have been made during real-world use of the prose editor in customer-facing products. I’m not completely happy about the way we’re specifying the editor configuration and haven’t been able to settle on either extensions or config as a keyword argument. The field supports both ways, at least for now. It’s probably fine. Releases django-auto-admin-fieldsets 0.2: I wrote a blog post here: Customizing Django admin fieldsets without fearing forgotten fields django-debug-toolbar 5.2: This release contains the second half of improvements from Djangonaut Space session four where I helped out as a Navigator. The toolbar properly supports code highlighting in dark mode, sanitizes request variables better, allows customizing redirects, supports projects using django-template-partials and more! FeinCMS 25.5.1: The first FeinCMS release of 2025. We’re still maintaining the project and fixing bugs! django-prose-editor 0.12: See above. django-json-schema-editor 0.4.1: Fixes much too small checkboxes when used inside tables. -
Python: a quick cProfile recipe with pstats
Python comes with two built-in profilers for measuring the performance of your code: cProfile and profile. They have the same API, but cProfile is a C extension, while profile is implemented in Python. You nearly always want to use cProfile, as it’s faster and doesn’t skew measurements as much. By default, cProfile’s CLI profiles a command and displays its profile statistics afterwards. But that can be a bit limited, especially for reading large profiles or re-sorting the same data in different ways. For more flexibility, cProfile can instead save the profile data to a file, which you can then read with the pstats module. This is my preferred way of using it, and this post covers a recipe for doing so, with a worked example. The recipe First, profile your script: $ python -m cProfile -o profile <script> [args] Replace <script> with the path to your Python file, and [args] with any arguments you want to pass to it. cProfile will run your script under its profiling machinery, saving the results to a file called profile, as specified by the -o option. Second, view the profile file using pstats: $ python -m pstats profile <<< $'sort cumtime\nstats 1000' | less …