23 Aug 2025

feedDjango community aggregator: Community blog posts

Menu improvements in django-prose-editor

Menu improvements in django-prose-editor

I have repeatedly mentioned the django-prose-editor project in my weeknotes but I haven't written a proper post about it since rebuilding it on top of Tiptap at the end of 2024.

Much has happened in the meantime. A lot of work went into the menu system (as alluded to in the title of this post), but by no means does that cover all the work. As always, the CHANGELOG is the authoritative source.

0.11 introduced HTML sanitization which only allows HTML tags and attributes which can be added through the editor interface. Previously, we used nh3 to clean up HTML and protect against XSS, but now we can be much more strict and use a restrictive allowlist.

We also switched to using ES modules and importmaps in the browser.

Last but not least 0.11 also introduced end-to-end testing using Playwright.

The main feature in 0.12 was the switch to Tiptap 3.0 which fixed problems with shared extension storage when using several prose editors on the same page.

In 0.13 we switched from esbuild to rslib. Esbuild's configuration is nicer to look at, but rslib is built on the very powerful rspack which I'm using everywhere.

In 0.14, 0.15 and 0.16 the Menu extension was made more reusable and the way extension can register their own menu items was reworked.

The upcoming 0.17 release (alpha releases are available and I'm using them in production right now!) is a larger release again and introduces a completely reworked menu system. The menu now not only supports button groups and dialogs but also dropdowns directly in the toolbar. This allows for example showing a dropdown for block types:

Screenshot showing prose editor dropdowns

The styles are the same as those used in the editor interface.

The same interface can not only be used for HTML elements, but also for HTML classes. Tiptap has a TextStyle extension which allows using inline styles; I'd rather have a more restricted way of styling spans, and the prose editor TextClass extension does just that: It allows applying a list of predefined CSS classes to <span> elements. Of course the dropdown also shows the resulting presentation if you provide the necessary CSS to the admin interface.

23 Aug 2025 5:00pm GMT

22 Aug 2025

feedDjango community aggregator: Community blog posts

Django News - State of Python 2025 Results - Aug 22nd 2025

News

State of Python 2025 Is Out!

Explore the key trends and actionable ideas from the latest Python Developers Survey, which was conducted jointly by the Python Software Foundation and JetBrains PyCharm and includes insights from over 30,000 developers.

jetbrains.com

PyPI now serves project status markers in API responses

PyPI now exposes standardized project status markers through its HTML and JSON index APIs, enabling package installers to programmatically signal dependency status and manage installations.

pypi.org

Preventing Domain Resurrection Attacks

PyPI now checks for expired domains to prevent domain resurrection attacks, a type of supply-chain attack where someone buys an expired domain and uses it to take an account through password resets.

pypi.org

Updates to Django

Today "Updates to Django" is presented by Velda Kiara from Django Events Foundation North America (DEFNA)! πŸš€

Last week we had 15 pull requests merged into Django by 10 different contributors - including a first-time contributor! Congratulations to Rohit for having their first commits merged into Django - welcome on board!

Django Core Updates ✨

Community Updates πŸ¦„

Want to celebrate Django's birthday with fellow Djangonauts? Head over to the Django20 website to attend one of the birthday celebrations to a city near you.

That's all for this week in Django development! πŸπŸ¦„

Django Newsletter

Wagtail CMS

Wagtail Space 2025 is a go!

Wagtail Space 2025 is a free three-day Zoom event featuring lightning talks and networking to shape future Wagtail improvements.

wagtail.org

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.

revsys.com

Articles

Sometimes LFU > LRU

Stop letting bot traffic evict your customers' sessions. A simple Redis configuration switch from LRU to LFU solved our crawler problem, with a Django configuration example.

revsys.com

Python Namespace Packages are a pain

Ensuring init.py is present in every directory prevents ambiguous namespace packages, streamlines module imports, and mitigates cryptic errors in Python packaging.

joshcannon.me

DjangoCon Africa x UbuCon 2025 Reflections: Stay For The Community

DjangoCon Africa x UbuCon 2025 underlines robust community collaboration, open-source initiative growth and challenges in sustaining African Django development through engaging sprints and talks.

scribe.rip

Customize your IPython shell in Docker

Customize your IPython shell in Docker with tailored profiles and startup scripts that streamline Django shell_plus debugging, imports, and UUID extraction workflows.

frankwiles.com

Best Python Books (2025)

An up-to-date list of the best books for learning Python.

wsvincent.com

Events

Friends of PyCon Africa Livestream

Join the August 30th livestream celebrating the vibrant Python community across Africa! This isn't your typical webinar - it's a dynamic, fun-filled conversation where Python community members will drop in and out throughout the event, sharing their stories, projects, and passion for Python.

Guests include Carlton Gibson, Dawn Wages, Michael Kennedy, Sarah Abderemane, and more.

pycon.org

Be Part of Something Amazing: Volunteer at DjangoCon US 2025 in Chicago!

Join DjangoCon US 2025 as a volunteer in Chicago to gain insider event management experience, expand your network, and strengthen the Django community.

djangocon.us

Videos

Talk Python Live Stream: Celebrating Django's 20th Birthday with its Creators

A discussion of Django's past, present, and future featuring Adrian Holovaty, Simon Willison, Thibaud Colas, Jeff Triplett, Will Vincent, and Michael Kennedy.

youtube.com

"How a Solo Hobbyist Learned to Love Testing" - Carl James

PyOhio talk on slowly integrating testing into Django apps and, by proxy, learning more about the underlying libraries along the way.

youtu.be

DjangoCon Videos

Logs, shells, caches and other strange words we use daily

This insightful talk reveals the unexpected origins of computing terms, linking historical context to modern software engineering practices relevant to Django experts.

djangotv.com

Sponsored Link 2

Sponsor this newsletter!

django-news.com

Podcasts

Django Brew #6: Celebrating 20 Years of Django

A podcast episode celebrates Django's 20th anniversary using trivia, reflections, and community updates to engage developers with historical highlights and events.

djangobrew.com

Test & Code | 238: So Long, and Thanks for All the Fish

Brian Okken reflects on a decade of Python testing and podcasting, sharing lessons learned and inviting continued engagement via his Python platforms. A farewell to a fun 10 years.

testandcode.com

Django News Jobs

Senior Python Developer at Basalt Health πŸ†•

Senior Full Stack Engineer at Lyst πŸ†•

Backend Python Software Engineer (Hybrid) at NVIDIA πŸ†•

Senior Python Developer at Brightwater

Senior Backend Engineer at Prowler

Django Newsletter

Projects

joshuadavidthomas/mcp-django-shell

MCP server providing a stateful Django shell for AI assistants.

github.com

edelvalle/djhtmx

Interactive UI components for Django using htmx.org.

github.com


This RSS feed is published on https://django-news.com/. You can also subscribe via email.

22 Aug 2025 3:00pm GMT

18 Aug 2025

feedDjango community aggregator: Community blog posts

Configurable UI in Software

Another short one today, that is a pattern I have noticed in a couple pieces of software I use, notably Todoist, Slack & Vivaldi. All three of these allow a user to configure the menu options to some degree. Slack has the option to customise the navigation options shown within a particular workspace to optimise the experience for a user. Todoist takes this a step further in the mobile app to allow a user to sort the menu items.

Browsers have always had a great experience of customisation, but Vivaldi takes this to an awesome extreme by allowing a user to customise each and every possible context menu, giving true flexability to their users.

Personally I have never considered the power of this and wonder if there are any efficient implementation of this for Django without creating a huge amount of complexity. The naive default solution would likely involve a model and a context processor and/or a middleware, it might be something I add in my next project, if we feel it would be beneficial to our users.

18 Aug 2025 5:00am GMT

15 Aug 2025

feedDjango community aggregator: Community blog posts

Django News - A New Django Fellow - Aug 15th 2025

News

Jacob Tyler Walls is Our New Fellow

Jacob Tyler Walls joins the Django Fellowship, bringing Django contributions, Triage and Review experience, ORM expertise, and GIS and open source maintenance skills.

djangoproject.com

Python 3.14.0rc2 and 3.13.7 are go!

Python 3.14 release candidates provide performance enhancements, new language features, and ABI stability, urging Django maintainers to prepare for compatibility testing.

blogspot.com

Announcing the PSF Board Candidates for 2025!

There are four board seats open for this year's PSF election. The timeline, voting details, and candidates are included in the post.

blogspot.com

Announcing Python Software Foundation Fellow Members for Q2 2025! πŸŽ‰

PSF announces Q2 2025 Fellows, recognizing new contributors who lead projects, maintain libraries, organize events, and mentor to grow the Python community globally.

blogspot.com

Django Software Foundation

DSF member of the month - Jake Howard

Jake Howard, DSF member and Django contributor, leads DEP 14 and develops Django tasks, advancing native background workers and task infrastructure for Django.

djangoproject.com

Building better APIs: from Django to client libraries with OpenAPI

Combine Django REST Framework with drf-spectacular to generate OpenAPI specs and use openapi-generator plus CI to produce and maintain automated client libraries.

djangoproject.com

Django's accessibility contributing guide

The Django accessibility team published contribution guidelines detailing practical testing, design steps, reporting workflow, and resources to help contributors make Django accessible to assistive technologies.

djangoproject.com

Updates to Django

Today, 'Updates to Django' is presented by Velda Kiara from Django Events Foundation North America (DEFNA)! πŸš€

Last week we had 16 pull requests merged into Django by 12 different contributors - including two first-time contributors! Congratulations to Xdynix and Alec Kerrigan for having their first commits merged into Django - welcome on board!

Django Core Updates ✨

Community Updates πŸ’œ

Djangonaut Space session 5 is open for applications. Session 5 will run from September 29th, 2025, to November 23rd, 2025. The deadline is September 14th, 2025.

Read more and apply through the link in the blog here.

That's all for this week in Django development! πŸπŸ¦„

Django Newsletter

Wagtail CMS

Front-end architecture fundamentals

Revisiting the fundamentals of the Web that Wagtail relies on

wagtail.org

Articles

pyx: a Python-native package registry, now in Beta

pyx is a Python-native package registry from the creators of uv.

astral.sh

Updating Python

Eric Matthes, author of Python Crash Course, covers this common question in his most recent "Mostly Python" newsletter. He shows how to clean up old pyenv and Homebrew Pythons in favor of adopting uv to install and manage Python interpreters and virtual environments.

mostlypython.com

Get started with event sourcing today

Use the eventsourcing Python package to learn Event, Aggregate, and Application patterns, then apply event sourcing to Django app domain logic with minimal infrastructure.

everydaysuperpowers.dev

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.

peterbe.com

HTTP Cats

API for HTTP Cats

http.cat

Django Fellow Report

Fellow Report - Natalia Bidart

3 tickets triaged, 9 reviewed, 1 authored, and other misc.

djangoproject.com

Fellow Report - Sarah Boyce

3 tickets triaged, 26(!) reviewed, and released Django 5.2.5.

djangoproject.com

Forum

Contributing opportunities list - Django Internals

A small project to list the contributing opportunities available in the Django community.

djangoproject.com

Events

DjangoCon Africa this week!

DjangoCon Africa has been taking place this week in Zanzibar. You can follow along on Fosstodon, LinkedIn, and other socials.

djangocon.africa

Django Girls Chicago - September 6th

Django Girls Chicago is happening during DjangoCon US week! A free one-day workshop for women beginners. No coding experience needed! Applications close August 23rd, 2025 - don't wait!

djangogirls.org

Introducing Keanya Phelps, DjangoCon US 2025 Conference Chair

A chat with Keanya Phelps about her role as Conference Chair and her experience with Django as a mid-life career changer.

djangocon.us

DjangoCon Videos

Bulletproof Data Pipelines: Django, Celery, and the Power of Idempotency

Learn how to build resilient data pipelines with Django, Celery, and idempotent consumers. We'll dive into robust error-handling techniques and the role of idempotency in ensuring reliable and consistent data processing.

djangotv.com

How to solve a Python mystery

Using Linux observability tools to learn what your Python application is doing.

djangotv.com

Django News Jobs

Backend Python Software Engineer (Hybrid) at NVIDIA πŸ†•

Senior Python Developer at Brightwater πŸ†•

Senior Backend Engineer at Prowler

Django Newsletter

Projects

dumaas/django-ulidfield

A drop-in Django model field for storing sortable, time-encoded ULIDs as 26-character strings.

github.com

adamghill/dj-lite

Configure SQLite for production use with Django.

github.com

Sponsorship

πŸ”– Book for Q3 2025!

Over 4,200 Django developers read Django News every week. If you have a product, service, or job to share, sponsoring an issue is a great way to get in front of them.

It's summer. People are building cool things. This is your chance to join the conversation.

πŸ‘‰ See sponsorship options

django-news.com


This RSS feed is published on https://django-news.com/. You can also subscribe via email.

15 Aug 2025 3:00pm GMT

14 Aug 2025

feedDjango community aggregator: Community blog posts

Standards for third-party packages

I am starting to feel like I have written about this too much as this point, but anyway, third-party packages again!

Recently I have been wondering about why third-party packages exist within the Django ecosystem. Broadly there is a few categories

Now one huge benefit to third-party packages is that it allows for choice, be it in the tools and dependencies used, the design and scope of the code. This is both for the package creator/maintainer and the user of said package. However I want to focus in on the last usage above and question whether choice is a good thing for this type of package.

If we were to build a package with the goal of it perhaps one day being merged into Django, would it not benefit our future selves and others if the overall design of the package matched Django conventions and standards whereever possible? For example, choosing unittest over pytest, or minimising the number of external dependencies that would be classed as unnecessary?

This has led to me to the idea of creating an 'official' template repo or cookiecutter template (or someother tool) that produces a repo for packages like this. Is it an extra maintanence burden? Yes, but I think it would greatly improve the new contributor story when they are told to create a package for their idea. And when I say official, ideally it would be within the Django Github organisation, but if it started in another place, say Django-commons, that would also work. I do wonder how it could be worked to lessen the maintenance burden though?

Good idea or not?

14 Aug 2025 5:00am GMT

12 Aug 2025

feedDjango community aggregator: Community blog posts

Why Open Source Makes Sense For Your Business Web Projects

What Is Open Source?

Open source software is publicly available code that anyone can use, modify, and improve. It's the foundation of much of the modern internet and it's trusted by global enterprises, startups, nonprofits, and government agencies alike.

12 Aug 2025 11:15pm GMT

11 Aug 2025

feedDjango community aggregator: Community blog posts

Happy 20th Birthday Django!

This Tuesday (tomorrow!), August 12th, we're teaming up with TriPython to host an informal Django Birthday event at Boxyard RTP in Durham.

11 Aug 2025 9:27pm GMT

09 Aug 2025

feedDjango community aggregator: Community blog posts

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.

09 Aug 2025 11:33pm GMT

08 Aug 2025

feedDjango community aggregator: Community blog posts

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 Events Foundation North America (DEFNA)! πŸš€

Last week we had 11 pull requests merged into Django by 7 different contributors - including 1 first-time contributor! Congratulations to Mridul for having their first commits merged into Django - welcome on board!✨

This week's highlights include:

Community News: Djangonaut Space is looking for contributors to be mentors for the next cycle of the program. Learn more about the program and how to get involved here!

That's all for this week in Django development! πŸπŸ¦„

Django Newsletter

Wagtail CMS

Enjoy better UX with Wagtail 7.1

Wagtail 7.1 improves the admin user experience with collapsible custom blocks, enhanced media listings, headless previews, keyboard navigation, and per-site permission controls.

wagtail.org

Annotating the Parent on a Page QuerySet

Demonstrates using Django ORM subqueries and custom database functions to annotate a parent field on Wagtail Page querysets while noting built-in alternatives.

bmispelon.rocks

What AI tools get right and wrong with Wagtail

A general look at how useful AI tools are for building Wagtail projects

wagtail.org

Sponsored Link 1

AI-Powered Django Development & Consulting

REVSYS specializes in seamlessly integrating powerful AI technologies, including GPT-4, into your existing Django applications. Your Django project deserves modern, intelligent features that enhance user engagement and streamline content workflows.

revsys.com

Articles

Boosting SEO with Django Ninja, Pydantic, and JSON-LD

Integrate SEO-friendly JSON-LD structured data in Django apps by generating and validating Schema.org schemas server-side using Django Ninja and Pydantic for maintainable, reusable code.

revsys.com

How JIT builds of CPython actually work

CPython JIT builds translate frequently executed bytecode into optimized native machine code using micro-ops and LLVM templates to improve runtime efficiency.

savannah.dev

How Python Grew From a Language to a Community - The New Stack

Python's evolution into a robust, community-driven ecosystem underpins modern frameworks like Django, fueling collaboration and innovation with sustained open source support.

thenewstack.io

User Timezones in Django

Implement user-specific timezones in Django by storing times in UTC, updating tzdata regularly, using zoneinfo for accurate conversions, and ensuring reliable datetime handling.

djangotricks.com

Loopwerk: Automate Python package releases

Automate Django package releases using tbump and GitHub Actions to update versions, run tests, lint code, and publish reliably to PyPI with minimal manual intervention.

loopwerk.io

TIL: Managing Editable Dependencies in uv Without Committing Local Paths

Dynamically switch uv dependency sources in pyproject.toml to maintain editable installations for local Django package development while enforcing production git sources via pre-commit hooks.

wersdoerfer.de

Flask or Django: Which One Best Fits Your Python Project?

Django's full-featured framework offers rapid development, robust security, and an integrated ORM that excels in building scalable, feature-rich applications compared to minimalist Flask alternatives.

appsignal.com

Forum

Removing non-HTML (PDF, EPUB, etc) documentation downloads

Proposal to drop Python documentation's PDF, EPUB, plain text, and texinfo builds to save resources and accelerate HTML docs updates.

python.org

Events

Announcing Our Keynotes: Carson Gross

Carson Gross is the creator of HTMX and his keynote integrates Django and HTMX with Nintendo Game Boy design principles for a hypermedia future.

djangocon.us

Django on the Med πŸ–οΈ

A free three-day Django sprint in Palafrugell offers focused development, detailed travel logistics, venue information, and community networking opportunities.

djangomed.eu

Announcing Our Keynotes: Zags (Benjamin Zagorsky)

Zags will deliver a DjangoCon US 2025 keynote exploring innovative Django use cases, advanced ORM enhancements, and advocating built-in JavaScript integration.

djangocon.us

Design Articles

A Friendly Introduction to SVG

Learn SVG fundamentals including inline SVG usage, shape primitives, viewBox configurations, and CSS animated strokes for creating dynamic scalable graphics within web projects.

joshwcomeau.com

DjangoCon Videos

Europe, Django and two-factor authentication - Agnès Haasser

A talk on why you should consider adding 2FA to your Django app, and how (quickly and easily) you can do it.

djangotv.com

Django News Jobs

Senior Backend Engineer at Prowler

Full Stack Engineer at LevPro

Backend Engineer at 7Learnings

Django Newsletter

Projects

loopwerk/django-generic-notifications

A flexible, multi-channel notification system for Django applications with built-in support for email digests, user preferences, and extensible delivery channels. - loopwerk/django-generic-notifica...

github.com

paduszyk/django-xlsx-serializer

Load/dump Django models from/to Excel 2007+ workbooks.

github.com

Sponsorship

🐍 Hey Django fans, want to get noticed?

Over 4,200 Django developers read Django News every week. If you have a product, service, or job to share, sponsoring an issue is a great way to get in front of them.

It's summer. People are building cool things. This is your chance to join the conversation.

πŸ‘‰ See sponsorship options

Django Newsletter


This RSS feed is published on https://django-news.com/. You can also subscribe via email.

08 Aug 2025 3:00pm GMT

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:

2025-08-05-documentation-that-is-never-wrong.png

This is a normal test that runs with the normal test suite, with some additional markup:

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 work across tests and docs.

08 Aug 2025 5:00am GMT

07 Aug 2025

feedDjango community aggregator: Community blog posts

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 a proxy for any environment that isn't development, it won't be a 100% accurate, but close enough I feel. (Side thought, what about a setting for named environments?)

Going further we could even exit the command early if DEBUG is False or show a prompt similar to collectstatic or even require setting a new environment variable to allow the check to be bypassed when DEBUG is False.

Additionally when the command is run successfully could we add a message along the lines of Be sure to commit these files to your version control tool of choice perhaps even doing a bit of introspection of directories to show the relevant commands in the message?

Any other thoughts on this? I am now half expecting to hear of all the legimate use-cases for running makemigrations when DEBUG is False! But I think this would be a useful addition to the command to prevent a footgun that happens fairly often for beginners.

07 Aug 2025 5:00am GMT

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 with an HTTP 400 telling you the name parameter is required.

So what. Big deal. The FastAPI Evangelism Strike Force will be along soon to bury you under rocket-ship emoji while explaining that FastAPI does the same thing but a million times better. And if you're a Java person used to Spring, or a .NET person used to ASP.NET MVC, well, there's nothing here that's new to you; you've had this style of annotation/signature-driven framework for years (and in fact one thing I like about Litestar is how often it reminds me of the good parts of those frameworks). And did anyone tell you FastAPI does this, too! πŸš€πŸš€πŸš€πŸš€πŸš€πŸš€πŸš€πŸš€πŸš€

But there are a lot of things that make Litestar stand out to me in the Python world. I'm going to pick out three to talk about today, and one of them is hiding in plain sight in that simple example application.

What's in a name?

You might see older material referring to Litestar as "Starlite", which was its original name.

Starlette is a toolkit for doing async Python web development, which can be used standalone or as a component in a more complex library or framework. FastAPI still uses Starlette under the hood, for example. And Litestar originally was built on Starlette too, and was named "Starlite", presumably in recognition of that. Over time, though, it dropped the Starlette dependency in favor of its own implementations for that functionality, and people on social media complained that the "Starlite" name was confusing, especially since Starlette was no longer being used. So the project which had been "Starlite" was renamed to Litestar for version 2.0, released in 2023, and has had that name ever since.

Scaling (the other kind)

It's a bit unfortunate that the term "scaling" is almost always assumed to mean handling larger and larger quantities of traffic, because that's only one axis on which any given piece of of technology can "scale" (and, I'd argue, possibly the least important one). The type of scaling I want to talk about here is scaling of a codebase: how does something (in this case, a web framework) help or hinder you as you deal with different amounts of code?

Django, for example, has a reputation for not scaling "down" all that well. You can do it if you really want to, and every so often someone will come up with a new demo of doing a Django project in a single Python file, but it's just not something that comes naturally to Django. Quite the opposite: if you work through the official beginner Django tutorial and do things the "Django way", you'll have around a dozen files laid out in a specific structure of directories and subdirectories before you've written a single meaningful line of your own code.

But "micro" frameworks have often had the opposite problem: they're great at starting out with a tiny single-file application, and then get painful as your codebase grows and needs to spread out (single-file Django approaches have the same problem: you have to do a lot of work to get a "micro-Django" working, and then you have to undo all that work as soon as the code grows large enough to be worth splitting across multiple files).

Let's look at an example. Here's a FastAPI equivalent of the basic Litestar application I showed above:

from fastapi import FastAPI


app = FastAPI()

@app.get("/greet")
async def greet(name: str) -> str:
    return f"Hello, {name}!"

Notice that the get() decorator here is attached to the application object. This is a common pattern (Flask/Quart do the same thing, for example, and Starlette used to but has deprecated its entire decorator-based routing system), but it creates a problem once you have multiple files. You need to import the main application object into the other files in order to decorate the routes, but you need to import the other files into your "main" application file to make sure the route registrations are visible from there, and now you have a circular import, and that doesn't work.

The general solution these frameworks offer is some sort of alternative sub-application object which can act as a per-file route registry that's safe to import into the file where your application object is defined. FastAPI calls this object an "API router"; Flask/Quart call it a "blueprint". Either way, it's a necessary construct for those frameworks because their route decorators are always bound to some parent object, either the application object in a single-file app or an "API router"/"blueprint"/etc. object in a multi-file app.

That solves the circular-import problem, but creates a new issue: the whiz-bang quickstart demos of "micro" frameworks generally register all the example routes on the application object in a single file in order to keep everything as simple and flashy as possible, but now in order to build a real application (which will almost never stay in a single file) you'll need to use a different mechanism, or start out following the demo and then switch later on. You also have to know about that different mechanism; in one framework's documentation that I looked at, you can (at the time I'm writing this post) apparently get 40 pages into the user guide before encountering the section on how to register routes in a multi-file app πŸ˜–πŸ˜–πŸ˜–.

Litestar avoids this entire mess by having the route decorators be standalone functions, not bound to a parent application or application-like object. This may seem like a small thing to focus on, but if you've spent time with popular Python microframeworks you've probably had to deal with the transition from single- to multi-file applications.

More importantly, this small change in approach frees up Litestar's documentation to introduce route-grouping constructs early on and to present them as part of a coherent layered architecture/configuration concept rather than as an escape hatch for avoiding circular imports. Which is great, because Litestar's layered architecture is one of its best features: its grouping constructs, and their ability to share configuration, offer an elegant way to compose functionality. For example, a common pattern I use when writing a set of CRUD endpoints looks like this):

from litestar import Router
from litestar.di import Provide

# Imagine some CRUD routes for widgets defined here...

_write_widget_router = Router(
    guards=[some_auth_function],
    route_handlers=[create_widget, delete_widget, update_widget])
)

widget_router = Router(
    dependencies={"widget_dependency": Provide(some_widget_dependency)},
    path="/widgets",
    route_handlers=[get_widget, get_widget_list, _write_widget_router]
)

This provides a single "public" Router instance with all the widget routes, all of which have access to the same core dependencies, but with the data-modifying routes also having auth applied. That composability is extremely powerful, and is less obvious if the "router" has to be introduced initially as a way to solve circular-import problems.

Litestar's approach also means it's easy to do things like register a single route multiple times, each with different configuration. Which enables use cases like:

If you know what you're doing, you can emulate some of this in the FastAPI/Flask style of bound route registration, but the techniques you'll end up using for that feel to me like fighting against the framework, which is something I usually want to avoid.

Not to be too Pydantic

Pydantic is a popular package for defining schema objects which perform validation and serialization/deserialization, driven by Python type annotations, and one major use case for this is the input/output schemas of web applications. FastAPI appears to use Pydantic exclusively, which comes with both upsides and downsides. Pydantic is very useful and very powerful, of course, but it also means FastAPI is somewhat limited by what Pydantic can support: mostly, this is Pydantic's own classes, and the Python standard library's dataclasses.

One crucial limitation is an inability to derive validation/serialization behavior directly from SQLAlchemy ORM classes, even though they both support a very similar type-annotation-based declaration format. Which means that to use SQLAlchemy with a Pydantic-only framework (and SQLAlchemy is basically the standard database toolkit and ORM for Python), you either have to write out the shape of your data multiple times-once for SQLAlchemy, and then at least one more time (possibly more than one time) for Pydantic-or turn to a third-party package to help bridge the gap. FastAPI's author worked around this by writing a new DB toolkit which combines SQLAlchemy and Pydantic, and pushing it in FastAPI's documentation.

Litestar, meanwhile, supports Pydantic, but is not tightly coupled to Pydantic, which gives a bit more flexibility. By default Litestar lets you define input/output schemas using Pydantic models, dataclasses, or msgspec; ships with plugins to enable the use of attrs and of SQLAlchemy models; and provides a protocol for writing your own serialization plugins to extend support to other kinds of objects.

That's very convenient already, but the convenience is amplified by Litestar's system for automatically deriving data-transfer objects from data-access or domain objects. Suppose, for example, that we have the following SQLAlchemy model class:

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

Base = DeclarativeBase()

class Widget(Base):
    __tablename__ = "widget"

    id: Mapped[int] = mapped_column(primary_key=True)
    internal_notes: Mapped[str]
    sku: Mapped[str] = mapped_column(unique=True)
    name: Mapped[str]
    price_cents: Mapped[int]

In a Pydantic-only world, we'd need to write multiple Pydantic models representing different use cases:

As well as possibly more schemas like an admin-view "read" schema that does include the internal fields, etc. Even if you get clever and use inheritance to share field definitions among all these Pydantic classes, you still will write out the full set of fields for widgets at least twice, and the second time it will be fragmented across multiple Pydantic classes, creating the risk of making a change to the ORM model and forgetting to update all the corresponding field definitions in the Pydantic models.

Litestar's approach is a significant improvement on this. For example, here's how to use Litestar's DTO helpers to define the "read" schema:

from litestar.dto import DTOConfig
from litestar.plugins.sqlalchemy import SQLAlchemyDTO

class ReadWidget(SQLAlchemyDTO[Widget]):
    config = DTOConfig(exclude={"id", "internal_notes"})

This will give you a DTO class containing all the fields of the Widget ORM model except the two explicitly excluded, and will derive that set of fields, and the correct data types, from introspecting Widget. It will also automatically handle conversion to and from instances of Widget when you specify it as the input or return DTO type of a route. Similarly, it's possible to declare a list of fields to include, or to re-map field names for public consumption, or to declare a DTO which makes fields optional for partial updates. This means there's only one canonical definition of the fields-on the original class, which might be a SQLAlchemy ORM model, might be a dataclass, etc.-and it doesn't have to be repeated in the DTOs because the DTOs will always derive their field definitions directly from the source class you point them at.

Of course, there are going to be cases where your DTOs are sufficiently different from your DAOs and domain objects that this isn't a big help, but my own experience is that "the DTO is a subset of the DAO's fields" is extremely common in real-world applications, so Litestar's approach really pays off in both reduced boilerplate and reduced errors from manual "transcription" of fields between different class definitions.

Alchemical architecture

I wasn't exaggerating earlier when I said that SQLAlchemy is the database toolkit and ORM for Python. While there are others out there, the only one I'm aware of that sees anything close to SQLAlchemy's usage is the Django ORM, and only because it's built into and tightly integrated with Django. So if you're going to be writing a database-backed web application in Python, and you're not doing Django, you are almost certainly going to be using SQLAlchemy.

And Litestar makes that easy. While officially remaining agnostic as to whether you even have a persistence layer, it still includes good integrations for SQLAlchemy: the serialization plugin mentioned earlier allows the direct use of SQLAlchemy ORM classes as input and output schemas; the DTO helpers can derive subsets and remappings of fields from SQLAlchemy ORM classes; and Litestar also ships with a plugin that manages a SQLAlchemy engine and per-request ORM session for you, as well as a single SQLAlchemy mega-plugin combining all the SQLAlchemy plugins' functionality.

So it's already pretty convenient to use SQLAlchemy in Litestar applications. But there's more! The Litestar team also maintains the excellent Advanced Alchemy library which provides a bunch of useful features on top of SQLAlchemy. While Advanced Alchemy is framework-agnostic, Litestar's SQLAlchemy plugin makes use of it and re-exports much of its functionality, giving you access to it automatically, and it does include Litestar-specific helpers for registering certain utility classes with Litestar's dependency injection.

Advanced Alchemy provides a lot of quality-of-life improvements for SQLAlchemy, including a variety of base classes and mixins and data types doing useful things like database-agnostic big-integer primary keys, automatic create/update timestamps, UUID-keyed models, a proper UTC timestamp type, and a JSON type which chooses the best column type for your database. There are also command-line helpers for database management (including creating and working with Alembic migrations), database dumping and seeding to/from JSON, and a lot more.

But the place where Advanced Alchemy really shines is in providing a generic repository implementation (both sync and async flavors) on top of SQLAlchemy models, along with a service-layer abstraction and helpers to integrate them into Litestar's dependency injection system.

Here's a basic example using the Widget class from above:

from litestar.plugins.sqlalchemy import repository

class WidgetRepository(repository.SQLAlchemyAsyncRepository[Widget]):
    model_type = Widget

WidgetRepository will have all the methods you'd expect-list(), get_one(), add(), delete(), etc.-automatically derived from the Widget model. And let me just say that having repository implementations automatically derived from any SQLAlchemy model, with not just basic CRUD operations but also things like paginated fetches, is a massive productivity boost compared to just using vanilla SQLAlchemy. It's maybe not quite on the level of Django's generic views, but it's a big step in that direction, and you probably could produce something like Django's generic views with Litestar and Advanced Alchemy if you wanted to (perhaps one day, in my copious free time, I'll even make an attempt at it).

I know it may seem strange to hear me saying this, since a few years ago I went on record as being strongly against these sorts of abstractions-specifically service layers-in Django. And I still think you absolutely should not try to retrofit repository or service-layer abstractions onto Django! They're not the native patterns of Django's architecture, and instead I think you should stick to what I recommended back then, which is to leverage Django's own architecture, especially its "manager" abstraction, rather than trying to force abstractions onto it that don't fit.

I also still think there are a lot of bad use cases for repositories and service layers that people should avoid, but that's a digression which should probably become its own post, so I'll just say for now that I think it's fine to use repositories and service layers as an organizing principle when you're using a less-structured framework which doesn't express strong opinions about how you should lay out your code. And that's exactly what I do when working with Litestar.

A lightweight star of Python

There are plenty of other features and conveniences in Litestar, many of which I use daily. Its auth system, supporting both simple guard functions and middlewares for attaching identity and complex authn/authz logic to requests. Its "stores" framework, which makes caching and similar tasks convenient. Its logging integrations which support both the Python standard library's logging module and popular third-party tools like structlog. Its built-in support for transforming errors to standard "problem details" structures. Its built-in support for recording and exporting metrics in standard Prometheus or OpenTelemetry formats. Its htmx support.

You can do this stuff in other microframeworks, but it typically involves a lot of tracking down of third-party add-ons and/or writing your own glue code to integrate things. Litestar manages to keep the "microframework" feel when starting a new project while also having all these nice bits optionally available with the framework itself when and if you decide you want them, and that's nothing to sneeze at. That's what I was getting at earlier when I said it reminds me of the things I like in certain frameworks from other languages. Litestar doesn't feel, to me, like it's trying to be a replacement for any pre-existing Python web framework. It's not trying to be the next Django or the next Flask or whatever; instead, it feels to me like a Pythonic take on the good parts of something like Spring Boot (and the way I like to set it up, doing things like using svcs behind the scenes as a service locator to feed things to both Litestar's and pytest's dependency injection, makes it feel even more that way).

I could go on for a lot longer listing things I like about Litestar, and probably wind up way too far into my own subjective preferences, but hopefully I've given you enough of a realistic taste of what it offers that, next time you're about to build a Python web app, you might decide to reach for πŸ’‘β­ to carry you to the moon πŸš€πŸš€πŸš€.

07 Aug 2025 12:25am GMT

02 Aug 2025

feedDjango community aggregator: Community blog posts

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 different channels like email or your website. It's built around the idea of defining notification types in your code, and then letting the library handle how and when to deliver them to your users.

Want to show a bell icon on your website when a user gets a new comment? Easy. Want to send them a weekly email digest with grouped notifications? Also easy. Want to build your own Slack or push notification integration? Go for it.

Highlights

Get started

Check out the project on GitHub: github.com/loopwerk/django-generic-notifications.

The README walks you through installation, configuration, and how to define your own notification types. You can be up and running in just a few minutes. Let me know how you like it!

02 Aug 2025 7:09pm GMT

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 page explaining that the answer is incorrect and no user account is created.

The results?

I am happy to report that ever since deploying this I did not spot any suspicious new account registration. Even though the "captcha" is super easy to defeat - I don't think anyone is going to create custom bot behavior for my small project.

]]

02 Aug 2025 2:28pm GMT

01 Aug 2025

feedDjango community aggregator: Community blog posts

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 (ATAG).

Improved GEOS error messages and tests, enhancing developer experience with better error messages.

That's all for this week in Django development! πŸπŸ¦„

Django Newsletter

Wagtail CMS

AI in the CMS: steering the ecosystem

Wagtail introduces opt-in, ethical AI enhancements that leverage Django's ecosystem for contextual alt text, content summarization, and improved admin customization.

wagtail.org

20,000 Django packages

Detailed PyPI analysis reveals over 23,000 Django packages with active releases, while Wagtail leverages both generic and specialized packages to boost development.

wagtail.org

Articles

Is AI Leaving the Python Community Behind?

Even as AI-focused talks dominate Python conferences, there is a corresponding lack of support from AI companies in the Python communities.

georgiker.com

Django: split `ModelAdmin.get_queryset()` by view

Customizing get_queryset per Django admin view using resolver_match.func.name enables precise database query optimizations that reduce unnecessary joins and improve performance.

adamj.eu

AI and Me: A Developer's Perspective

Reflections on using AI in software development-from autocomplete gripes to Claude Code breakthroughs, and why agents need seniors, not sorcery.

someonewho.codes

Our tools are still not designed for the AI future

The article explores an AI-first IDE paradigm that prioritizes agent workflows and spec-driven development to transform coding and code review processes.

softwarecrafts.co.uk

Why We Need to Stop Fighting About AI Tools and Start Teaching Them

LLM-based coding agents streamline boilerplate production so that Django developers can concentrate on building innovative architecture and solving complex design challenges.

ryancheley.com

Loopwerk: Why Django's DATETIME_FORMAT ignores you (and how to fix it)

Django admin defaults to 12-hour clocks due to locale precedence, but developers can enforce 24-hour time by configuring FORMAT_MODULE_PATH and translation overrides.

loopwerk.io

From Not Knowing Programming Was a Job to GSoC and Contributing to Django Core

Contributed inline template partials to Django core for improved component reuse and rendering via HTMX amid a journey from novice programmer to GSoC participant.

farhana.li

Thoughts on HTML mails

Implement HTML notification emails using Django send_mail to deliver visually appealing, skimmable messages with a clear call-to-action and enhanced accessibility.

hyteck.de

I was wrong about robots.txt

A good lesson about unintended consequences that may come out of blocking all UserAgents in your robots.txt file.

evgeniipendragon.com

Events

The DjangoCon US 2025 schedule has been released!

DjangoCon US 2025 schedule includes diverse Django talks covering AI deployment, project maintainability, high performance techniques, and MongoDB integration among other topics.

djangocon.us

Getting to know folks: A pre-conference interview

DjangoCon US 2025 pre-conference interview highlights community diversity, organizer insights, and speaker experiences to foster mentorship and global excitement for Django development.

djangocon.us

DjangoCon Videos

One Thousand and One Django Sites with Vince Salvino

Told in the storybook style of "One Thousand and One Nights" (a.k.a. "Arabian Nights") this talk will feature real-world stories about strategies and challenges we have encountered along our journey of hosting over 1,000 Django/Wagtail sites.

djangotv.com

Django Admin at Scale: From Milliseconds to Microseconds with Sumit Singh

Is your Django Admin crawling with millions of records? Join me in exploring battle-tested optimization techniques that transform Django Admin from sluggish to lightning-fast. From smart queries to caching strategies, you'll learn practical solutions to scale your admin interface while keeping it user-friendly. Performance isn't just a feature-it's a necessity!

djangotv.com

Just-in-Time Development with Django and HTMX: Faster, Leaner, and Smarter with Thomas De Bonnet

Learn how Just-in-Time development with Django & HTMX can make your apps faster and more efficient! Fetch only what users need, when they need it-like loading dropdown data on hover or filling a modal when opened. Boost performance, save resources, and enhance UX!

djangotv.com

Sponsored Link 2

AI-Powered Django Development & Consulting

REVSYS specializes in seamlessly integrating powerful AI technologies, including GPT-4, into your existing Django applications. Your Django project deserves modern, intelligent features that enhance user engagement and streamline content workflows.

revsys.com

Podcasts

Abstractions: Semi-Coherent Output

Abstractions discusses evolving AI challenges and layered technologies affecting software development dynamics relevant to modern Django application practices.

pod.link

Django News Jobs

Senior Backend Engineer at Prowler

Full Stack Engineer at LevPro

Backend Engineer at 7Learnings

Django Newsletter

Projects

simonw/simonwillisonblog

The source code behind Simon Willison's high-traffic personal site.

github.com

ephes/django-indieweb

Just some of the indieweb endpoints for Django.

github.com

Sponsorship

Lightning-Fast Python: Mastering the uv Package Manager - Livestream on August 7th

Register for an upcoming livestream featuring Michael Kennedy, host of Talk Python to Me and Python Bytes podcasts, on August 7th at 11am Eastern Daylight Time (UTC-4).

jetbrains.com


This RSS feed is published on https://django-news.com/. You can also subscribe via email.

01 Aug 2025 3:00pm GMT

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.

01 Aug 2025 5:00am GMT