01 Oct 2025
Django community aggregator: Community blog posts
I Miss Tabs vs Spaces... And Other AI Musings
A written guide to my DjangoCon US talk on deploying machine learning models with Django.
01 Oct 2025 6:56am GMT
15 Sep 2025
Django community aggregator: Community blog posts
Full text search with Django and SQLite
One thing I wanted to add to this blog for a long time was full text search. Content is steadily increasing and sometimes I have a hard time finding the exact right post to link to when writing a new post. My wife was also complaining that she could never find the post about backups for artists when she wanted to link it. So what a better way to spend a few hours of my vacation than to add full text search functionality.
Usually when adding search to a system people eye ElasticSearch. A monstrosity I had my fair share of "fun" with and something I do not want to touch if I can avoid it. Avid Postgres users might lean on PostgreSQLs excellent full text search and vectorisation options. This blog is running on Django and SQLite and there is no chance I would add either of these two to the stack for "just a blog".
SQLite has an extension for full text search. Technically multiple, but we are using FTS5. Per documentation we need a virtual table and fill it with our data. For the table we add the title of the post and its raw content. A row ID
is automatically generated for you and we will use this as a back reference to our post IDs. (Please do not ask me why name
and not title
. There are good(tm) reasons)
create virtual table search USING fts5(name, content);
The big question is how to get data into the table. We could create an unmanaged model, setup post_save
receivers and let Django do its magic. Or we create a few triggers for insert, update and delete in SQLite. I am usually not a fan of this approach, especially with larger codebases and / or teams. But there is a fairly good chance no one but me will ever touch this code.
CREATE TRIGGER post_insert
AFTER INSERT ON blog_post BEGIN
INSERT INTO search (rowid, name, content)
VALUES (new.id, new.name, new.content);
END;
And we obviously want to backfill all existing content.
INSERT INTO search (rowid, name, content) SELECT id, name, content FROM blog_post;
Since rowid
is automatically generated we re-use it to set it to the content tables ID. It feels like adding a separate field for that might be cleaner, but I also have not found any suggestion that manually managing row IDs is a bad idea. So here we are, being super efficient, not storing 300 additional integers!
Creating the table and setting up the triggers happens in an empty database migration.
Querying the search index in Django is fairly easy thanks to Django exposing a database connection to run raw SQL queries with. But we are using a raw database connection, so the general guidance and warnings about using params
, etc. to prevent SQL injections apply.
cursor.execute("SELECT rowid, rank FROM search WHERE search MATCH %s ORDER BY rank", (query,))
The query returns the rowid
which is the ID
of our post and a rank. The data is already ordered, no need to further sort it. With Case
and When
we preserve the order when fetching posts by ID from the database.
ids = [doc[0] for doc in result]
ordering = []
for idx, val in enumerate(ids):
ordering.append(When(id=val, then=Value(idx)))
return self.published().filter(id__in=ids).order_by(Case(*ordering, output_field=IntegerField()))
I uploaded the model manager and migrations, which will likely make it a bit clearer how things are set up. The triggers need to be created in a separate migration from the one creating the virtual table. I am not yet sure why this is the case, but this was the only way to reliably create the triggers. There is a try / catch blog in the model manager that will make a lot more sense in a second.
Limitations
I think this search works well enough for my blog. But there are some noticeable limitations, especially when you are used to services requiring a distributed cluster to figure out of there is a document with the name "foo".
SQLites FTS really does not like any special characters like >
. This is fine. Also do not take this as an invitation to hammer this server with some automated sql injection tools to verify it is actually working as expected. Thanks in advance.
sqlite3.OperationalError: fts5: syntax error near ">"
There are ways to make this work by wrapping >
in quotation marks ">"
but this means FTS5 will query for an exact match for the string.
The second thing that will be obvious very quickly when misspelling a word is that there is no fuzzy search. backpu
will not bring up the article about backup strategies. Neither will back
. Word matches only.
There is also no custom weighting of title matches vs content matches.
Improving Search
One option is to use a different tokeniser which will make search behave more like traditional search you know. There is a porter
tokeniser implementing the Porter stemming algorithm which will make sure running
matches run
. There is also a trigram
tokeniser indexing three character sequences for partial matching. I still want to run some experiments to see if it is worth using either of them. For some content and use cases it will absolutely be worth it, I cannot imagine building search for e-commerce with them.
Tokenisers support some more options including unicode vs ascii tokenisers and handling diacritics.
Weighting and ranking should be solvable using SQLites bm25()
method. I am saying should be solvable because a quick test on my data did not influence the rank at all, even if the content got a 10x boost over the title. There is a fairly good chance this is me messing up, but I do not think this will be a big enough difference to not rollout search v1.
The real fun begins when we install Python with a compile time option to load extensions in SQLite and compile the spellfix1 SQLite extension. This should help with correcting misspelled words and should work with FTS5. I did not spend enough time playing with spellfix, but from its description I think it is doing what you would expect when you ever hand rolled fuzzy search.
I am curious if spellfix will be worth the effort or if it will be easier to query the FTS5 vocabulary table and calculate the Levenshtein distance in memory considering the fairly small dataset of this blog.
Good enough
Compared to an ElasticSearch cluster, PostgreSQL and all the other fancy search engines out there this seems very rudimentary and more like a toy. But for this blog it is more than good enough. The fact that something exists is already a huge improvement.
But do not let this simple example make you believe this is all FTS5 is capable of. It is worth quickly scanning the FTS5 documentation to get an idea what is possible, because there is a lot in there including some fun stuff like custom tokenisers, external content references and contentless tables to highlight and snippet functions that could come in very handy in certain situations.
I already toyed around with some of the tokenisers and spellfix, but I will need a bit more time for testing and to actually compare them to ElasticSearch to get an idea how good they actually work and what the pitfalls are. I will likely iterate on search every now and then and see what is feasible to do in SQLite. So far I am more than pleasantly surprised and I already was a fan of SQLite before.
15 Sep 2025 4:58pm GMT
uv Livestream with Michael Kennedy
An in-depth look at the uv package manager, why it is so popular, and how to use it today.
15 Sep 2025 10:56am GMT
DjangoCon US 2025 Recap
Thoughts on a fun week in Chicago, favorite talks, sprints, and more.
15 Sep 2025 10:56am GMT
14 Sep 2025
Django community aggregator: Community blog posts
Django views versus the Zen of Python
A while ago, I wrote about how I write Django views, arguing that the base View
class hits the sweet spot between the simplicity of function-based views and the often-overwhelming complexity of generic class-based views. The response to that article made it clear that I'm not alone in this thinking.
It got me wondering: why does this approach feel so right? The answer, I believe, lies in the guiding principles of Python itself. The Zen of Python isn't just a collection of clever aphorisms; it's a framework for writing clear, maintainable, and effective code. When we look at Django's view layer through this lens, it becomes apparent where things start to go astray.
Here are all the ways that Django's views (especially the generic class-based kind) break the Zen of Python.
"There should be one - and preferably only one - obvious way to do it."
Python developers cherish this principle. It promotes consistency and readability. Yet, when it comes to something as fundamental as rendering "Hello, world!" in Django, the options are dizzying.
Just look at the many ways to accomplish this simple task:
The simple function:
from django.http import HttpResponse
def hello_world(request):
return HttpResponse("Hello, world!")
The base View
class:
from django.http import HttpResponse
from django.views import View
class HelloWorldView(View):
def get(self, request):
return HttpResponse("Hello, world!")
The generic TemplateView
:
from django.views.generic import TemplateView
class HelloWorldView(TemplateView):
template_name = "hello.html"
The render
shortcut:
from django.shortcuts import render
def hello_world(request):
return render(request, "hello.html")
The TemplateResponse
:
from django.template.response import TemplateResponse
def hello_world(request):
return TemplateResponse(request, "hello.html")
This abundance of choice leads to inconsistency across projects and even within a single codebase. It creates cognitive overhead for new developers who are forced to learn five ways to do one thing. By standardizing on a single, clear pattern, like the base View
class, we can bring a project back in line with this core Pythonic principle.
"Flat is better than nested."
Have you ever tried to understand where the magic in a generic DetailView
comes from? You might need a map. The inheritance tree for even the most common generic views is a deep, tangled web. A DetailView
inherits from SingleObjectTemplateResponseMixin
, BaseDetailView
, which inherits from SingleObjectMixin
, ContextMixin
, and finally the base View
.
This nesting is the antithesis of "flat." Logic is scattered across multiple parent classes, making it difficult to track down the source of behavior. Contrast this with the base View
. All its methods-get()
, post()
, setup()
, dispatch()
-are at the same level. The logic is right there in front of you, not hidden five levels deep in an inheritance tree.
"If the implementation is hard to explain, it's a bad idea."
This follows directly from the last point. The deep nesting of generic CBVs makes them incredibly hard to explain. To truly understand how a DetailView
works, you need to read the method flowcharts in the documentation and trace method calls like get()
, get_context_data()
, and get_object()
across five different classes.
Contrast with this: "A request comes in, the dispatch
method on the View
class checks the HTTP method, and then it calls the method with that name, like get
or post
. That's it."
One of these is a bad idea. When you have to keep a mental map of a framework's internal machinery just to display a single database object, the abstraction has failed. It has become more complex than the problem it was meant to solve.
"Errors should never pass silently."
This is one of my biggest frustrations, and it lies in Django's template language. By design, the template engine swallows errors. If you make a typo in a variable name, it doesn't raise an AttributeError
or KeyError
. It fails silently, rendering an empty string.
This design decision has a direct impact on debugging our views. Did I forget to add user_profile
to my context dictionary in the get_context_data
method? Did I misspell it as user_pofile
in the view? Or did I misspell it in the template? The silent failure makes it much harder to pinpoint the source of the bug, forcing you to debug in three places at once. This is a clear violation of a principle designed to make debugging easier.
"Practicality beats purity."
The Django template language was designed with the "purity" of separating logic from presentation in mind. It's a noble goal, but in practice, it has led to some deeply impractical limitations.
It's wild to me that after all these years, we still can't do something as basic as mydict[key]
or mylist[0]
in a template. Instead, we have to reinvent the same getitem
template tag in nearly every project.
This is a classic case of purity getting in the way of practicality. The template language is intentionally crippled in its capabilities to enforce a philosophical ideal, leaving developers with a less powerful and more frustrating tool.
Finding the path
Django is a powerful and wonderful framework, but like any tool, it can be misused. The generic class-based view system, in its attempt to be a one-size-fits-all solution, often creates more complexity than it saves.
By returning to the principles of the Zen of Python, we can find a better way. The base View
class offers a more Pythonic path. It's simple, not complex. It's flat, not nested. Its implementation is easy to explain. It encourages us to be explicit and to build solutions that are practical and maintainable for the long term.
Django doesn't force you to write views in a way that violates the Zen of Python, but it often nudges you there. By resisting the pull of generic CBVs and sticking with simpler patterns, you can build Django projects that feel a lot more like Python itself.
14 Sep 2025 5:00am GMT
12 Sep 2025
Django community aggregator: Community blog posts
LLMs are making me a better programmer...
LLMs are making me a better programmerβ¦
I'm still undecided about LLMs for programming. Sometimes they are very useful, especially when working on a clearly stated problem within a delimited area. Cleaning the code up afterwards is painful and takes a long time though. Even for small changes I'm unsure if using LLMs is a way to save (any) resources, be it time, water, energy or whatever.
They do help me get started, and help me be more ambitious. That's not a new idea. Simon Willison wrote a post about this in 2023 and the more I think about it or work with AI the more I think it's a good way to look at it.
A recent example which comes to mind is writing end to end tests. I can't say I had a love-hate relationship with end to end testing, it was mostly a hate-hate relationship. I hate writing them because it's so tedious and I hate debugging them because of all the timing issues and the general flakyness of end to end testing. And I especially hate the fact that those tests break all the time when changing the code, even when changes are mostly unrelated.
When I discovered that I could just use Claude Code to write those end to end tests I was ecstatic. Finally a way to add relevant tests to some of my open source projects without having to do all this annoying work myself! Unfortunately, I quickly discovered that Claude Code decided (ha!) it's more important to make tests pass than actually exercising the functionality in question. When some HTML/JavaScript widget wouldn't initialize, why not just manipulate innerHTML
so that the DOM looks as if the JavaScript actually ran? Of course, that's a completely useless test. The amount of prodding and instructing the LLM agent required to stop adding workarounds and fallbacks everywhere was mindboggling. Also, since tests are also code which has to be maintained in the future, does generating a whole lot of code actually help or not? Of course, the amount of code involved wasn't exactly a big help when I really had to dig into the code to debug a gnarly issue, and the way the test was written didn't exactly help!
I didn't want to go back to the previous state of things when I had only backend tests though, so I had to find a better way.
Playwright codegen to the rescue
I already had some experience with Playwright codegen, having used it for testing some complex onboarding code for a client project I worked on a few years back, so I was already aware of the fact that I could run the browser, click through the interface myself, and playwright would actually generate some of the required Python code for the test itself.
This worked fine for a project, but what about libraries? There, I generally do not have a full project ready to be used with ./manage.py runserver
and Playwright. So, I needed a different solution: Running Playwright from inside a test!
If your test uses the LiveServerTestCase
all you have to do is insert the following lines into the body of your test, directly after creating the necessary data in the database (using fixtures, or probably better yet using something like factory-boy):
import subprocess
print(f"Live server URL: {live_server.url}")
subprocess.Popen(["playwright", "codegen", f"{self.live_server_url}/admin/"])
input("Press Enter when done with codegen...")
Or of course the equivalent invocation using live_server.url
when using the live_server
fixture from pytest-django.
Of course Tim pointed me towards page.pause()
. I didn't know about it; I think it's even better than what I discovered, so I'm probably going to use that one instead. I still think writing down the discovery process makes sense.
TLDR
Claude Code helped getting me to get of the ground with adding end to end tests to my projects. Now, my tests are better because - at least for now - I'm not using AI tools anymore.
12 Sep 2025 5:00pm GMT
Django News - Djangonaut Space 2025 Session 5 - Sep 12th 2025
News
Djangonaut Space 2025 Session 5 Applications
Applications are open until September 14 end of day. This is your last chance to apply if interested!
Getting Started With Open Source Through Community Events
Django community events empower developers to gain practical open source contribution experience via office hours, sprints, testathons, and live PR review sessions boosting personal growth.
DjangoCon US: Call for Venue Proposals 2027-28
So you want your city to host DjangoCon US? Hurrah! We're delighted by your interest. Here's what you need to know, and what we need to know, to consider your proposal.
Django Software Foundation
DSF at EuroPython 2025: Celebrating 20 years of Django
EuroPython 2025 featured DSF's vibrant booth and collaborative sprints to commemorate Django's 20th anniversary, uniting contributors and strengthening community ties.
Updates to Django
Today, "Updates to Django" is presented by Raffaella from Djangonaut Space! π
Last week we had 12 pull requests merged into Django by 11 different contributors - including 1 first-time contributor! Congratulations to Ronan LE HAY for having their first commits merged into Django - welcome on board!
In Django 6.0, the DEFAULT_AUTO_FIELD
setting now defaults to BigAutoField
, completing the transition that began in Django 3.2. Most projects should already be prepared, but if you relied on the old behavior, you can set DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
in your settings.
Django Newsletter
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
Fat Posts in Django
Leveraging Django proxy models and custom ModelForms enables dedicated admin views for specific post types, facilitating flexible content management and refactoring.
Proposal: django.contrib.beginners
A proposal suggests developing a django.contrib.beginners
app to centralize warnings, helpful views, and experimental code, enhancing onboarding and future Django core integrations.
Ready prek go!
Prek, a Rust-based alternative to pre-commit leveraging uv for Python environment management, achieves notable performance improvements and reduced disk usage for hook installations.
Customizing your Python REPL's color scheme (Python 3.14+)
Python 3.14 introduces syntax highlighting that developers can customize via PYTHONSTARTUP
with the experimental _colorize module, ideal for matching editor themes.
Using direnv to add a personal `.gitignore` file to repos
Integrate direnv to auto-update .git/info/exclude
with .gitignore.local
contents and logging, ensuring repository-specific ignore rules remain effective.
One command to run them all
Using just command runner consolidates diverse project commands into a uniform interface that reduces friction and enhances Django project management with tailwind integration.
Django for AI: My DjangoCon US 2025 Conference Talk
A written out guide to Will Vincent's DjangoCon US talk on Django for AI.
Django Fellow Report
Django Fellow Report - Natalia
An especially intense week covering as much as possible ahead of 6.0 Feature Freeze and :airplane: trip to DjangoCon US.
6 tickets triaged, 13 reviewed, and 2 authored. Also... onboarding new Fellow Jacob, monthly Ops call, attended DSF Office Hours, and more.
Django Fellow Report - Sarah
A big welcome to Jacob for his [now second] week as a Django Fellow!
7 tickets triaged, 13 reviewed, 3 authored. Engaged in Google Summer of Code project, security topics, fellow onboarding discussions, and more.
Django Fellow Report - Jacob
Jacob's second week as a Fellow! Please welcome him on the Forum if you haven't already.
3 tickets triaged, 9 reviewed, 7 authored, 3 discussed. Combined with onboarding, security reports, and generally getting up-to-speed with Fellowing!
Forum
Django needs a REST story
Django aims to incorporate native REST API support by evaluating direct integration, DRF absorption, and enhanced documentation to address modern API demands.
Events
Sprints are the best part of a conference
Conference sprints deliver significant productivity gains and foster real-time collaboration among developers, boosting open source contributions and accelerating project momentum in Python communities.
Django News Jobs
Full Stack Developer (Contract) at Three Tablets LLC π
Django Developer at The Developer Society π
Affiliate Python / Django Tech Lead at AND Digital
Backend Engineer (Python) (Consultant) at Syria Justice and Accountability Centre (SJAC)
Django Developer at The Developer Society
Senior Python Developer at Basalt Health
Senior Full Stack Engineer at Lyst
Backend Python Software Engineer (Hybrid) at NVIDIA
Django Newsletter
Projects
j178/prek
β‘ Better pre-commit
, re-engineered in Rust
archesproject/arches
Arches is a web platform for creating, managing, & visualizing geospatial data. Arches was inspired by the needs of the Cultural Heritage community, particularly the widespread need of organizations to build & manage cultural heritage inventories.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
12 Sep 2025 3:00pm GMT
11 Sep 2025
Django community aggregator: Community blog posts
Django for AI: My DjangoCon US 2025 Conference Talk
A written guide to my DjangoCon US talk on deploying machine learning models with Django.
11 Sep 2025 6:56am GMT
10 Sep 2025
Django community aggregator: Community blog posts
Weeknotes (2025 week 37)
Weeknotes (2025 week 37)
I'm having a slow week after the last wisdom tooth extraction. Finally! I'm slowly recuperating from that.
Also, I'm trying to split up the blog posts a bit and writing more standalone pieces instead of putting everything into weeknotes. This seems like a good idea to publish more, and should also help me when I try to find a particular piece of writing later.
Releases
- django-content-editor 8.0.2: I fixed the ordering calculation in the cloning functionality; the tests are a bit too forgiving for my taste now but I just can't figure out why the gap for inserting cloned items is sometimes larger than it should be. It doesn't matter though, since ordering values do not have any significance, they only have to provide a definite ordering for content items.
- django-prose-editor 0.18.2: Cleaned up the documentation after the 0.18 cleanup (where automatic dependency management has been removed), fixed table styles when using dark mode.
10 Sep 2025 5:00pm GMT
08 Sep 2025
Django community aggregator: Community blog posts
Proposal: django.contrib.beginners
A few weeks back I wrote about a suggestion for a new warning in regard to makemigrations, which got some feedback on the fediverse some was positive, others a bit crictial of the other warning I was recently responsible for in 5.2. Anyway one suggestion from Carlton in that thread was interesting, the idea of app for beginners. It also reminded me of a conversation I had with Thibaud last year where he made a comment that with Wagtail features & changes, they try to consider the potential infinite future developers of the software over the fixed number of past developers that have already used Wagtail. So having a place where we prioritise future users and developers over the existing backward compatibility conerns is an interesting one to me.
The idea is simply to put all of these beginner style warnings in to an app specifically for beginners. This easily contains the extra code into a couple of lines of configuration (as much configuration as any other third-party package). This could be a simple thing that then tutorials/books could recommend, it could possibly make it's way into a starter template for Django itself (perhaps when DEP 15 is implemented).
The goal of this app would be two-fold, first have a place to put warnings, helpful views or other code and common configuration that often trips up beginners. This code could even recommend or install other third-party packages. Some of this code would be operational (eg the warnings) and other aspects could be reference (eg views, forms or models). The secondary goal would be a place for us to experiment with ideas before they move to core, but get broad usage from new developers.
I think is something I will experiment with in the near future once I have completed a few other Django related tasks I have on my list!
08 Sep 2025 5:00am GMT
05 Sep 2025
Django community aggregator: Community blog posts
Django News - Last call for DjangoCon US 2025 tickets! - Sep 5th 2025
News
ποΈ Last call for DjangoCon US 2025 tickets!
DjangoCon US kicks off this Monday, September 8th - 12th in Chicago, IL USA. Online tickets are still on sale!
If you are attending this year, Will, Jeff, and Catherine from this newsletter will be there. Say hello in person or virtually.
Online tickets are only $99 USD and include three days and over 50 talks!
Django security releases issued: 5.2.6, 5.1.12, and 4.2.24
Django releases critical security patches in versions 5.2.6, 5.1.12, and 4.2.24, addressing high-severity SQL injection vulnerabilities in FilteredRelation
column aliases via dictionary expansion.
Keyboard shortcuts in Django via GSoC 2025
GSoC 2025 delivers django-admin-keyshortcuts
, a package that improves Django admin navigation and accessibility with customizable keyboard shortcuts, aiming for eventual inclusion in Django core.
Django MongoDB Backend Now Generally Available
The new Django MongoDB Backend provides production-ready integration, enabling Django ORM, admin, and DRF usage with MongoDB Atlas features for scalable, flexible deployments.
Python Type System and Tooling Survey 2025
Python Type System and Tooling Survey 2025 gathers insights on type hint practices, challenges and tooling usage to enhance static typing integration in Django projects.
Django Software Foundation
DSF member of the month - Lilian
DSF names Lilian member of the month for her active contributions in code reviews, community mentoring, and enhancing Django projects through participation in Djangonaut Space.
Updates to Django
Today, "Updates to Django" is presented by Raffaella from Djangonaut Space! π
Last week we had 25 pull requests merged into Django by 12 different contributors - including 1 first-time contributor! Congratulations to Mustafa Pirbhai for having their first commits merged into Django - welcome on board!
- Removed
:py
domain in the documentation. (ticket #36570) - In Django 5.2 is fixed a bug where using
QuerySet.values()
orvalues_list()
with aForeignObject
composed of multiple fields returned incorrect results instead of tuples of the referenced fields (ticket #36431). - Added view decorators for adjusting the CSP configuration per-view. (ticket #36532).
- Enforced absolute targets for
:doc:
in docs.
Djangonaut Space Session 5 is still open for application π Discover more here
Django Newsletter
Sponsored Link 1
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.
Articles
Looking forward to Django 6.0
A monthly "The Stack Report" update from Carlton Gibson about the upcoming release of Django 6.0.
django-prodserver is live
django-prodserver provides a management command API for configuring production processes in Django with extras for gunicorn, uvicorn, waitress, celery, django-tasks, and more.
Open Source is a Gift
Open source public development enriches Django tooling by enabling collaborative learning and iterative innovation, exemplified by a Django language server built in Rust.
Python has had async for 10 years -- why isn't it more popular?
Although async has existed in Python for a decade, Django's async improvements lag behind async-first frameworks due to concurrency challenges and GIL limitations.
Python: capture stdout and stderr in unittest
Improve Django unit tests by capturing stdout, stderr, and log messages using contextlib redirection techniques, StringIO buffers, and pytest capsys for robust output verification.
Forum
Performance regression from using `email.message.Message.get_params()` as replacement of `cgi.parse_header` following PEP 594 - Python Help - Discussions on Python.org
Switching to email.message.Message.get_params
for parsing Content-Type
headers in Django has introduced significant performance overhead on every request in WSGI and ASGI setups.
Events
My DjangoCon US 2025 Plans (and How to Find Me)
Jeff and Will will be in Chicago for DjangoCon US 2025, inviting online participation while discussing Django development, AI integration, and community sustainability topics.
Make the Most of Your Trip to DjangoCon US 2025
Tips from Jon Gould of Foxley Talent on how to maximize your DjangoCon US experience.
An Insider's Guide to DjangoCon US 2025
Advice on attending DjangoCon US next week in Chicago, from the hallway track to the sprints, social events, exercise clubs, and more.
Videos
Programming for Yourself with Paul Ganssle
Mastering programming empowers developers to create custom solutions for personal challenges, a strategy that resonates with Django's dynamic and scalable design.
Building a Smart Morning Routine Dashboard (From a Jailbroken Lululemon Mirror)
Build a smart routine dashboard on a jailbroken Lululemon mirror using Django and Jetson Nano to integrate calendar, tasks, affirmations and weather.
Sponsored Link 2
Reach 4,000+ Django Developers!
Sponsorship spots are available, either single week ads or bundle deals.
Podcasts
Episode #518 - Celebrating Django's 20th Birthday With Its Creators
Django's 20-year evolution highlights its stable ORM, integrated admin, and thriving community while adapting to async, HTMX, and modern web development trends.
Django News Jobs
Full Stack Developer (Contract) at Three Tablets LLC π
Django Developer at The Developer Society π
Affiliate Python / Django Tech Lead at AND Digital π
Backend Engineer (Python) (Consultant) at Syria Justice and Accountability Centre (SJAC) π
Django Developer at The Developer Society π
Senior Python Developer at Basalt Health
Senior Full Stack Engineer at Lyst
Backend Python Software Engineer (Hybrid) at NVIDIA
Senior Python Developer at Brightwater
Django Newsletter
Projects
nanorepublica/django-prodserver
Contribute to nanorepublica/django-prodserver development by creating an account on GitHub.
khanxmetu/django-admin-keyshortcuts
Keyboard shortcuts for Django Admin
Sponsorship
π Sponsor Django News for Q3 2025!
Django News reaches more than 4,200 Django developers every week. With a 52% open rate and a 15% click-through rate, our readers are not just subscribers; they are a highly engaged community. Sponsoring an issue is a powerful way to put your product, service, or job in front of developers who take action.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
05 Sep 2025 3:00pm GMT
04 Sep 2025
Django community aggregator: Community blog posts
How to Make the Most out of DjangoCon US 2025
Tips on having the best conference experience.
04 Sep 2025 9:56pm GMT
An Insider's Guide to DjangoCon US 2025
Tips on having the best conference experience.
04 Sep 2025 9:56pm GMT
Talk Python: Celebrating Django's 20th Birthday With Its Creators
Recording a recent podcast appearance with Simon Willison, Adrian Holovaty, Will Vincent, Jeff Triplet, and Thibaud Colas.
04 Sep 2025 6:56am GMT
Leiden python meetup: memory graph - Bas Terwijn
(One of my summaries of the fifth Python meetup in Leiden, NL).
Full title of the talk: memory graph: teaching tool and debugging aid in context of references, mutable data types, and shallow and deep copy.
memory_graph is a python debugging aid and teaching tool. It is a modern version of python tutor. (There is an online demo)
Python has two categories of types:
- Immutable types: bool, int, float, str, tuple, etcetera. They cannot be mutated, so when a value is changed, a copy is made. If you add an item to a tuple, you get a new tuple with the extra item.
- Mutable types: dicts, lists. You can change the values without the actual dict/list changing. You can add items to a list and you still have the same list object.
When you want an actual copy of a mutable type, you need to use import copy and copy.copy(your_list). And copy.deepcopy().
- list2 = list1 is an assignment.
- list2 = copy.copy(list1) gives you a second, separate, list object, but it points at the same values inside it as list1.
- list2 = copy.deepcopy(list1) gives you a second, separate, list object and separate copies of the values inside it.
Watch out with the list2 = list1 assignment. When you add an item to list2, it is also "added" to list1 as it is the same.
He had a couple of simple exercises for us, which were amusingly hard :-)
Apart from the web online demo, there are also integrations for jupyter notebooks and lots of IDEs. Here's an animated gif from the github repo:

04 Sep 2025 4:00am GMT
Leiden python meetup: HTMX - Jan Murre
(One of my summaries of the fifth Python meetup in Leiden, NL).
The person who invented htmx (Carson Gross) always begins with hypermedia. Hypermedia is a media that includes non-linear branching from one location in the media to another, via hyperlinks. HTML is hypermedia, the world's most succesful hypertext.
Another important term: HATEOS, hypermedia as the engine of application state. With hypermedia, state is on the server. So not in a javascript frontend. With traditional single page apps that you see nowadays, you only read some json and the frontend needs to know what to do with it. Lots of logic is on the client. And you get "javascript fatigue".
With hypermedia, you have server-side rendering. Minimal javascript. Progressive enhancement. SEO friendly. And... accessible by default. The content you get includes the behaviour (like a link to delete an item).
HTMX extends HTML with modern interactivity using simple attributes. You can target specific elements on your page for an update, so you don't need to get a full page refresh. And you can use any http verb (get/post/put/delete/patch). And you're not limited to forms and links: any element can trigger a request.
Some attribute examples:
- hx-get issues a GET request to the server when you click on the element.
- hx-post, same with POST.
- hx-target, what you get back from your get/post, where do you want to place it?
- hx-swap: just replace part of the page.
- hx-trigger: when to do the request. Based on a click or based on a timer, for instance.
An advantage of HTMX is maintainability. Complexity is way lower than a single page app. Familiar patterns and regular server-side logic. Much simpler. Accessible (provided you put in some effort).
He showed a nice example with a generated list, a search field and a form. Nice: extra validation on one of the form fields via a hx-post and a hx-trigger="on-blur".
Nice trick for hx-target: you can give it the value of "closest .some-css-class", then it finds the closes enclosing element with that class.
Other niceties: hx-indicator enables a spinner upon a POST and disables it once the POST succeeds. <div hx-boost="true"> around your content tells HTMX to replace your whole page's content with the new page, the result is the same as normally, only without the temporary flicker when loading the page.
HTMX is great for:
- CRUD applications.
- Content-heavy sites.
- Forms and validation.
- Server-side rendered apps.
- Progressive enhancement.
- Moderate interactivity.
You can read a book about HTMX here: https://hypermedia.systems/
04 Sep 2025 4:00am GMT