Django community: RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Combining Django signals with in-memory LRU cache
It's easy to combine functools.lru_cache with Django signals to get a good memoization pattern on Django ORM queries. -
Django News - Django 5.2.5 Released - Aug 8th 2025
News Django bugfix release issued: 5.2.5 Django 5.2.5 provides essential bug fixes to boost application stability and performance, ensuring smooth deployments and improved developer experience. djangoproject.com django-rest-framework release v3.16.1 DRF v3.16.1 fixes unique_together and source field bugs, removes legacy Python support, and enhances translations, documentation, and internal testing with Django 5.2 compatibility. github.com Python Insider: Python 3.13.6 is now available Python 3.13.6 incorporates extensive bug fixes, build improvements, and documentation updates that enhance overall performance and reliability essential for Django applications. blogspot.com Join the Mission: Session 5 Applications Open! 🎉 Djangonaut Space opens applications for Session 5, an eight-week group mentorship guiding contributors to make sustained contributions to Django core and related projects. Applications open August 10th, 2025. djangonaut.space Preventing ZIP parser confusion attacks on Python package installers PyPI will reject malformed or ambiguous wheel ZIPs and begin enforcing RECORD consistency to prevent ZIP parser confusion attacks across Python installers. pypi.org Django Software Foundation DSF member of the month - Jake Howard Jake Howard, DSF member and Django contributor, details his DEP 14 background workers, community involvement, and focus on enhancing Django security and performance. djangoproject.com Updates to Django Today 'Updates to Django' is presented by Velda Kiara from Django … -
Documentation that is never wrong
The iommi docs are more correct than most projects because we take a different approach to documentation: part of the test suite is the documentation. Let’s look at an example: def test_grouped_fields(): # language=rst """ .. _group-fields: How do I group fields? ~~~~~~~~~~~~~~~~~~~~~~ .. uses Field.group Use the `group` field: """ form = Form( auto__model=Album, fields__year__group='metadata', fields__artist__group='metadata', ) # @test show_output(form) # @end This ends up as this documentation: This is a normal test that runs with the normal test suite, with some additional markup: The triple quoted strings that are declared with # language=rst are included in the docs. Code is by default included in the documentation You can exclude code with # @test/# @end for checks you don’t want to include in the docs show_output renders some HTML output into a file that is then shown inline in the finished docs The .. uses command is used to mark what features this test uses so the examples are automatically linked from the reference API docs With this infrastructure in place, some fixes or features can be implemented with all the required tests written as the documentation with no additional tests. This radically incentivises writing docs compared to duplicating … -
A beginner check for makemigrations
Could our tools be smarter (even without AI) and helpful to prevent footgun usage? Today I'm taking aim at the Django makemigrations command. I feel fortunate to have been introduced to South and Django migrations at the beginning of my career so the logic of the migration files and the workflow makes sense in my head (or if I was confused I was corrected very early on by colleagues). However I wonder what other tech stack's do in regard to keeping keeping code and schema's in sync. I question this as every so often I run into newcomer's to Django not commiting migration files to source control and running makemigrations in every environment, which if you didn't know is a very bad idea that will lead to numerous issues as the project progresses. This led me to the following question: Could we prevent this happening in the first place, or place a burden on those knowing the risks when taking them? My immediate answer to this is spit out a warning if someone tries to run makemigrations when the DEBUG setting is False. To me this should be the minimum to add to the command. Using the DEBUG setting is … -
Litestar is worth a look
A few years ago at work, I had a project which offered an opportunity to look at the new generation of async-first, type-hint-driven Python web frameworks. For reasons which aren’t particularly relevant today, on that project I ended up choosing Litestar, which is the one that doesn’t have a ravenous all-consuming hype machine surrounding it. And I’m very glad I did, because today I’m more convinced than ever it was the right choice, and for the last 18 months or so every new project I’ve started at my day job has been built with Litestar. But even if you’re someone who does Python web apps for a living, and even if you’re someone who builds asynchronous type-hint-driven web apps, you might not be familiar with this absolute gem of the Python web ecosystem, and today I want to remedy that. A taste Here’s the traditional single-file-app demo: from litestar import Litestar, get @get("/greet") async def greet(name: str) -> str: return f"Hi, {name}!" app = Litestar([greet]) You save this as app.py, run with litestar run or hand it directly to the ASGI server of your choice, and it launches a web application. You go to /greet?name=Bob and it replies “Hi, Bob!”. Leave out the name parameter and it responds … -
Announcing django-generic-notifications 1.0.0
Back in 2011, I started a small Django package called django-generic-notifications. It was built for a project I was working on at the time, got seven releases over a few months… and then it more or less died. Once I moved on from that original project, there wasn’t much reason to keep maintaining the library. It never gained a big user base, no pull requests or issues came in, and eventually I archived the repository. Fast forward to a few weeks ago, and I found myself needing a good, flexible notification system for a new Django project. I checked out a few third-party options, but none of them quite fit what I had in mind. I wasn’t super eager to revive django-generic-notifications — it was very old, still using South for migrations (yes, that old) — but in the end, I decided to bring it back to life. Or rather, to start fresh. So here it is: version 1.0.0 of django-generic-notifications. A complete rewrite, with the same core architecture but a modern, cleaned-up implementation. It’s more flexible, more powerful, and a lot more useful. What is django-generic-notifications? At its core, this package helps you send notifications to your users through … -
Solving bots registration problem by “reinventing the wheel”
<![CDATA[ Solving bots registration problem by “reinventing the wheel” Ever since I launched ImpressKit in 2021 I had issues with spammy bot registrations. Usually at least a few times a month these would be like twenty new user accounts that were obviously bots. I figured that it just a cost of having product with registration but over the years I got more and more annoyed. It messed up my stats dashboard, I was sending emails to weird addresses and I think I even got complaint from someone saying the did not register after receiving a login confirmation email. Some months ago I finally had enough and decided to try to tackle this. I did not want to use 3rd party captcha because these are annoying and it is another part that I would need to monitor and possibly update… But what should I use? After some thinking I arrived at solution that seemed both simple and like it could work. I added required “questionnaire” to the register form asking the prospective user what the project is about. I made sure the correct answer wasn’t the first radio button. When incorrect option is selected, then the form just redirects to new … -
Django News - Django and AI - Aug 1st 2025
News Djangonaut Session 5 - Officer and Organizer Interest A form to gauge returning officer and session organizer interest for the next session! google.com PyPI Users Email Phishing Attack - The Python Package Index Blog Phishing emails exploit PyPI package metadata by directing users to fake login pages that mimic PyPI, prompting developers to verify URLs and update passwords. pypi.org Djangonaut Space is looking for contributors to be mentors Posted by Djangonaut Space session organizers on July 31, 2025 djangoproject.com Updates to Django Today 'Updates to Django' is presented by Pradhvan from the Djangonaut Space! 🚀 Last week we had 16 pull requests merged into Django by 11 different contributors including 3 first-time contributors! Congratulations to Anthony Sottile, Mohamed Amine Mahmoud and Take Weiland for having their first commits merged into Django, welcome on board! 🎉 This week's Django highlights 🌟 Migrated django.core.mail to Python's current email API, replacing legacy email handling with modern implementation. Added hints support for PostgreSQL contrib operations, enabling database routers to make informed decisions in multi-database migration scenarios. Introduced accessibility guidelines and established accessibility standards that conform with the Web Content Accessibility Guidelines (WCAG) standards and along with best practices from Authoring Tool Accessibility Guidelines … -
Python and AI workflow with LangGraph
In this stream, I worked on a personal AI workflow that I’m building using LangGraph. I discussed human-in-the-loop and how to bring a person into the workflow process. -
Django: write a custom URL path converter to match given strings
Here’s a little tip based on some work that I did recently. The project has a URL pattern where the first part of the URL matches the current role the user is viewing the site as. Let’s say the roles are “chef”, “gourmand”, and “foodie”—example URLs might look like this: /chef/dashboard/ /gourmand/dashboard/ /foodie/dashboard/ /chef/dish/1/ /gourmand/dish/1/ /foodie/dish/1/ Most views can be accessed under all roles, with restrictions applied within the view code where appropriate. To match the role parts of the URL, you could define each URL pattern individually: from django.urls import path from example import views urlpatterns = [ path("chef/dashboard/", views.dashboard), path("gourmand/dashboard/", views.dashboard), path("foodie/dashboard/", views.dashboard), path("chef/dish/<int:id>/", views.dish), # ... ] However, that gets tiresome quickly and doesn’t really scale to larger numbers of roles or views. Also, it slows down URL resolution, as Django has to check each pattern in turn. Some scalable alternatives would be: Using Django’s str path converter, as in: path("<str:role>/dashboard/", views.dashboard) However, this matches arbitrary strings, requiring extra validation in the view and care to avoid capturing other URLs. Reaching for re_path() to define the URL as a regular expression, like: re_path(r"^(chef|gourmand|foodie)/dashboard/$", views.dashboard) But regular expression syntax is more complicated, especially for matching parameters. Rather than … -
Django: split ModelAdmin.get_queryset() by view
Within Django’s popular admin site, you can override ModelAdmin.get_queryset() to customize the queryset used by the admin views. It’s often used for performance optimizations, such as adding a select_related() call to batch-fetch related objects: from django.contrib import admin from example.models import Book @admin.register(Book) class BookAdmin(admin.ModelAdmin): def get_queryset(self, request): return super().get_queryset(request).select_related("author") However, one thing this approach lacks is granularity—the queryset returned by get_queryset() is used for all admin views, such as the change list, change form, and any custom views that you might add. That can mean that adding an optimization in get_queryset() for one view can impose a performance cost on other views that don’t need it. For example, the above select_related() call might optimize showing author details shown on the change list view, but other pages that don’t show the author will still incur the cost of the join. There isn’t an easy way to customize the queryset for individual views without overriding a lot of their code. However, the queryset() method is passed the current request object as context, which allows you to differentiate between views based on request.resolver_match. I think the most robust way to check the current admin view from there is with the __name__ attribute … -
Our tools are still not designed for the AI future
First a disclaimer on this one: I am making the assumption that the AI trend is here to stay in some form and an economic crash/bubble doesn't make the usage of them untenable, also I have yet experiment with every tool out there! With that said, a brief personal history of my usage of LLM's and the current wave of AI. I tried out ChatGPT when it was first released and was fairly impressed by the results, but the cruical missing step for me was the lack of browser integration, searching Google was still much quicker from a new tab page and the results from ChatGPT felt isolated, there was too much friction in my workflow for it be usable. I tried out a different product (I forget the name), which allowed me to search from a new tab page and I got AI results and normal search results in one go. This was better, but it still didn't stick, and so I kept experimenting with the tools on an ad-hoc basis, solving small challenges, but it not being a daily driver. In this I experimented with local LLMs and Zed's AI integration. This changed earlier this year where I … -
User Timezones in Django
When you create a local website, the local time usually matches your country’s timezone, and all visitors see times in that timezone. That’s not a big issue if your country has only one timezone and your audience is local. But when building a social platform like pybazaar.com, users are international and need to see times in their timezones. In this article, I’ll show you how to handle that in Django. Time Zone Database Since version 4.0, Django has used the zoneinfo library for managing timezones, and it used pytz up to version 3.2. Both rely on the IANA Time Zone Database (tzdata). IANA is the same organization that manages the DNS root zone, IP addresses, and other global internet resources. Install tzdata in your virtual environment as usual: (venv)$ pip install --upgrade tzdata Timezone Changes Timezone information changes several times a year due to: Daylight Saving Time (DST) adjustments Political and border changes Shifts in standard time offset Daylight Saving Time (DST) was first introduced in 1914 in Canada and later standardized in the U.S. in 1966. When dealing with historic dates before 1966—or future dates with uncertain timezone rules—precise time calculations can be unreliable. # Before U.S. DST standardization: … -
Django News - DjangoCon US 2025 Talks Announced - Jul 25th 2025
News Announcing our DjangoCon US 2025 Talks! The official DjangoCon US 2025 talk lineup has been unveiled, featuring expert sessions on Django deployments, ORM alternatives, search, AI integration, CMS, migrations, performance, and community practices. djangocon.us Python 3.14 release candidate 1 is go! This is the first release candidate of Python 3.14. blogspot.com PSF Board Election Nominations Opening July 29th PSF opens 2025 Board Election nominations from July 29 to August 12 UTC, providing a timeline, resources, and guidance for prospective candidates. blogspot.com Updates to Django Today 'Updates to Django' is presented by Pradhvan from the Djangonaut Space! 🚀 Last week we had 14 pull requests merged into Django by 8 different contributors including 2 first-time contributors! Congratulations to LauHerregodts and Ishita Jain for having their first commits merged into Django, welcome on board! 🎉 This week's Django highlights 🌟 Deprecated most positional args to django.core.mail, adding deprecation warnings for non-keyword arguments in email functions, with removal planned for Django 7.0. Added support for GeometryType database function, bringing new GIS functionality for spatial queries with cross-database compatibility including Oracle. Updated migration command to record applied/unapplied migration statuses recursively, fixing how Django handles double-squashed migrations to ensure proper status tracking. That's all … -
Deploying a Django App to Sevalla
This tutorial looks at how to deploy a Django application to Sevalla. -
Latest feature of Comfort Monitor Live released!
Yesterday I finally finished and released the latest feature of Comfort Monitor Live, which allows users to design custom layouts for the comfort monitor. This has been build has been a long slog of over 6 months slowly working on it every Wednesday evening for a couple of hours. AI has helped to an extent in building this feature, but mostly it was still me slowly building and debugging issues as they came up. Being a chrome extension, means a lot of Javascript and I the UI has been NextJS. Both of these have made me realise the beauty and speed Django brings to a project for CRUD operations against a datastore and a structure for quickly creating a UI that can store that data. This was also one of those features which resulted in a rebuild of the core logic to be better and scalable for future use, especially the next feature which will allow the user to implement some rules around how the comfort monitor runs during an event. It's going to be another big lift when I do build it, but for now, with this shipped it's going to allow me to focus more on some Django … -
Django: iterate through all registered URL patterns
I’ve found it useful, on occasion, to iterate through all registered URL patterns in a Django project. Sometimes this has been for checking URL layouts or auditing which views are registered. In this post, we’ll look at a pattern for doing that, along with an example use case. Get all URL patterns with a recursive generator The below snippet contains a generator function that traverses Django’s URLResolver structure, which is the parsed representation of your URLconf. It extracts all URLPattern objects, which represent individual URL patterns from path() or re_path() calls, and returns them along with their containing namespace. It handles nested URL resolvers from include() calls by calling itself recursively. from typing import Iterator, Optional from django.urls import URLPattern, URLResolver, get_resolver def all_url_patterns( url_patterns: Optional[list] = None, namespace: str = "" ) -> Iterator[tuple[URLPattern, str]]: """ Yield tuples of (URLPattern, namespace) for all URLPattern objects in the given Django URLconf, or the default one if none is provided. """ if url_patterns is None: url_patterns = get_resolver().url_patterns for pattern in url_patterns: if isinstance(pattern, URLPattern): yield pattern, namespace elif isinstance(pattern, URLResolver): if pattern.namespace: if namespace: namespace = f"{namespace}:{pattern.namespace}" else: namespace = pattern.namespace yield from all_url_patterns(pattern.url_patterns, namespace) else: raise TypeError(f"Unexpected pattern type: … -
Django News - 🎂 Django Turns 20! - Jul 18th 2025
News 🎂 Happy 20th birthday Django! On July 13th 2005, Jacob Kaplan-Moss made the first commit to the public repository that would become Django. Twenty years and 400+ releases later, here we are – Happy 20th birthday Django! 🎉 djangoproject.com 📻 W2D Django 20th Celebration Continues 🎂 Nearing one week in, two operators of the W2D special event station honoring Django's 20th birthday have made over 400 contacts with 22 geopolitical entities on 4 continents. github.com Prohibiting inbox.ru email domain registrations A recent spam campaign against PyPI has prompted an administrative action, preventing using the inbox.ru email domain. This includes new registrations as well as adding as additional addresses. pypi.org Affirm Your PSF Membership Voting Status If you are a voting member of the Python Software Foundation and you plan on voting this year, here are the details you need to know for how to vote. If you voted in 2024, you are still eligible to vote in 2025; however, we recommend double-checking your status to ensure accuracy. blogspot.com Updates to Django Today 'Updates to Django' is presented by Pradhvan from the Djangonaut Space! 🚀 Last week we had 7 pull requests merged into Django by 7 different contributors including … -
Why Django's DATETIME_FORMAT ignores you
When you start a new Django project, you get a handful of default settings for localization and timezones: settings.py USE_I18N = True LANGUAGE_CODE = "en-us" USE_TZ = True TIME_ZONE = "UTC" I’ve written before about the default timezone being a silly choice for sites with a global user base, both on the backend and the frontend. But today, I want to talk about internationalization (I18N) and language settings. For my sites, LANGUAGE_CODE = "en-us" is perfectly fine; all my admin users speak English, and we prefer American spelling over the British variant. But there are some weird things going on in Django that I want to address. The USE_I18N puzzle Here’s the first weird thing. The default settings have USE_I18N = True, which enables Django’s internationalization features. The default LANGUAGES setting also includes a massive list of every language under the sun. You’d think this means the Django Admin would automatically switch languages. If I set my browser’s preferred language to Dutch, shouldn’t the Admin follow suit? Nope. It remains stubbornly English. It turns out you need to add this to your middleware for the translation to actually happen: settings.py MIDDLEWARE = [ # ... "django.middleware.locale.LocaleMiddleware", ] Only after adding … -
Django at 20: a personal journey through 16 years
Django turned 20 a few days ago, which is a remarkable milestone for any software project. I’ve been along for most of that ride, starting my Django journey in September 2009. That’s almost 16 years ago! It’s been fascinating to watch both Django and my use of it evolve over time. From server-rendered pages to APIs and back When I started with Django in 2009, it was a different world. Everything was server-rendered, with a bit of jQuery sprinkled in. I wrote my very first Django article in November 2009 about dynamically adding fields to models. This was quickly followed by articles on what I didn’t like about Python and Django and how to use Jinja2 templates in Django, which solved some of my pain points. In 2012, my focus shifted dramatically. I went from full-time web developer to full-time iOS developer. Django didn’t disappear from my life though, it just changed roles. Instead of building full websites, I was creating REST APIs to power mobile apps, which is when I discovered Django REST Framework. Fast forward to 2023, and I’ve come full circle, returning to full-time web development. These days, I mostly use SvelteKit on the frontend with Django … -
How to Get Foreign Keys Horribly Wrong
Constraints keep the integrity of your system and prevent you from shooting yourself in the foot. Foreign keys are a special type of constraint because, unlike unique, check, and primary keys, they span more than one relation. This makes foreign keys harder to enforce and harder to get right. In this article, I demonstrate common pitfalls, potential optimizations, and implicit behavior related to foreign keys. Table of Contents Naive Implementation Enhanced Implementation Replacing unique_together Identifying Duplicate Indexes Identifying Blocking Migrations Safely Migrating Foreign Key Reversible Migration Operations Concurrent Index Operations Indexes on Foreign Keys Partial Foreign Key Indexes Using Built-in Concurrent Index Operations Order Migration Operations Locking Across Relations Permissive No Key Locks The Final Model Takeaways The Mandatory AI Angle Watch 📺 This article is inspired by a talk I gave at DjangoCon EU. Watch it here. Naive Implementation Imagine a simple application to manage a product catalog: Generated using dbdiagram.io The first table, or model, in the catalog is the Category model: class Category(models.Model): id: int = models.BigAutoField(primary_key=True) name: str = models.CharField(max_length=50) Categories can be "household items", "fruit", "apparel", and so on. Next, a model to store products: class Product(models.Model): class Meta: unique_together = ( ('category', 'category_sort_order'), ) … -
Happy Birthday to Django!
Over the weekend Django celebrated being 20 years since the first public commit. This is an incredible achievement for a community led project. Django is behind some tiny projects to those that scale globally and personally my career wouldn't be where is it without Django. Most of my career existed with only a vague awareness of the community, but since getting involved on Discord and beyond has been great for my soul and enjoy those that share the passion of seeing Django succeed. So as we celebrate 20 year's would be to get involved if you use Django, go to an event, donate to the DSF or join us in the community (online and in person). If you work for a company that use's Django lobby them to donate as well! I am excited for the next decade of slow but sure progress and the community being healthier than ever before. -
Django News - Django's Ecosystem - Jul 11th 2025
News Django’s Ecosystem The official Django website has added a new page called “Django’s Ecosystem” with a list of resources and 3rd party packages. djangoproject.com Python Release Python 3.14.0b4 It's the final 3.14 beta! Beta release previews are intended to give the wider community the opportunity to test new features and bug fixes and to prepare their projects to support the new feature release. python.org Updates to Django Today 'Updates to Django' is presented by Pradhvan from the Djangonaut Space!🚀 Last week we had 5 pull requests merged into Django by 5 different contributors - including 2 first-time contributors! Congratulations to Roelzkie and matthews-noriker for having their first commits merged into Django - welcome on board! 🎉 This week's Django highlights 🌟 Improved staticfiles manifest reproducibility, fixing nondeterministic file ordering for consistent deployments. Enhanced composite primary key infrastructure, fixing __in tuple lookups on database backends lacking native tuple comparison support. That's all for this week in Django development! 🐍 🦄 Django Newsletter Wagtail CMS 10 Underrated Django Packages 10 underrated Django packages according to the annual Django Developers Survey. wagtail.org Sponsored Link 1 Scout Monitoring: Logs, Traces, Error (coming soon). Made for devs who own products, not just tickets. scoutapm.com … -
What if Django was written in a new language..
So this is a bit of a follow on from Day 277 and taking the premise of the idea presented with it and pushing it further. What if we, as a community decided to (re-)write Django in another language? It's not as wild as you might think, Lily Foote is currently tackling an implementation of the Django template language in Rust and someone else suggested that URL resolving might benefit from a similar treatment. However that is not the goal of this push forward, but it is again Django as design pattern or set of API's. If we wanted to allow someone to migrate Django (or even part of it) to a new language, some comphrensive API documentation outside the codebase and inside the codebase would be a good start. And as I write this I realise that we do have this, it's the amazing test suite that helps to make Django stable (that's all 17898 tests and counting), but even then a test suite is never the whole story. Today was more of a pondering thought and not a complete one at that, but more of a thought experiment and a consideration (to myself more than anyone) of what … -
Python Leiden meetup: Handling crash reports with Bugsink - Klaas van Schelven
(One of my summaries of the fourth Python meetup in Leiden, NL). Bugsink is a tool/website for collecting error messages from (for instance) your websites. You get an email or other notification and you can visit the error page. You'll see the exact error and a traceback and the environment variables and the library versions. But... isn't that just like sentry? Yes. Mostly. But... why bugsink? It is self-hostable. Originally, 20 years ago, sentry was also self-hostable, but it isn't anymore. There's a bit of workflow, too. You can mark issues as "fixed in the next release". Bugsink will then ignore new occurrences of the error until it notices you made a release. It is not just in the same market as sentry, it is even sentry-compatible. If you already have sentry set up, moving to bugsink only means changing the SENTRY_DSN setting. The API is the same. Self-hosting? You can run a docker. He showed that pip install bugsink also works. It is just a plain regular django site with migrate and runserver. A single instance can easily handle 1.5 million errors per day. Some generic tricks (whether sentry or bugsink): Just use your error tracker in development, too! …