11 Aug 2026

feedDjango community aggregator: Community blog posts

Duff's device in JavaScript

In 1983, Tom Duff needed to copy memory into an output register faster than his compiler could manage, and wrote the most famous abuse of switch in the history of C. I ported his device to JavaScript and raced it against the plainest possible loop - and the verdict changed with the engine, the engine's version, and the CPU underneath.

Duff’s device in JavaScript

11 Aug 2026 10:00am GMT

08 Aug 2026

feedDjango community aggregator: Community blog posts

Django: introducing django-msgspec

It's another day, another new package day here. Say hello to django-msgspec, a package of drop-in replacements for Django and Django REST Framework (DRF) components backed by msgspec.

msgspec is a C-based serialization library covering JSON, MessagePack, YAML, and TOML, with optional schema validation through typed Struct classes. Its JSON encoder and decoder are several times faster than the standard library's, which makes django-msgspec a cheap performance win in the parts of Django that handle JSON.

Features

There's a version of JsonResponse:

from django_msgspec.http import JsonResponse


def index(request):
    return JsonResponse({"title": "Hello, world!"})

…a test client with matching test case classes:

from django_msgspec.test import SimpleTestCase


class IndexTests(SimpleTestCase):
    def test_index(self):
        response = self.client.get("/", headers={"accept": "application/json"})
        assert response.status_code == 200
        # response.json() uses msgspec to parse the response body
        assert response.json() == {"title": "Hello, world!"}

…a version of Django's json_script template tag, which is where this whole story began:

{% load django_msgspec %}
{{ sales_by_product_id|json_script:"chart-data" }}

…and a handful of components that you activate purely through settings, with no code changes at all:

SESSION_SERIALIZER = "django_msgspec.sessions.JSONSerializer"

SERIALIZATION_MODULES = {
    "json": "django_msgspec.serializers.json",
    "jsonl": "django_msgspec.serializers.jsonl",
}

REST_FRAMEWORK = {
    "DEFAULT_RENDERER_CLASSES": ["django_msgspec.rest_framework.JSONRenderer"],
    "DEFAULT_PARSER_CLASSES": ["django_msgspec.rest_framework.JSONParser"],
}

That covers session storage and signing, dumpdata / loaddata in both JSON and JSON Lines, and DRF request parsing and response rendering.

Everything encodes with an enc_hook that knows about Django's lazy strings, so translated text passes through as you'd expect. It's all tested against the currently supported versions of Python and Django, with 100% coverage.

Déjà vu?

Only three weeks ago, I introduced django-orjson, a near-identical package backed by the Rust-powered orjson. So yeah, you might be confused why I made another faster-alternative-JSON-package-wrapper package so soon after the first one.

After releasing django-orjson, several folks from the community reached out to me telling me about the issues with orjson and pointing to msgspec instead. Additionally, while trying to roll out django-orjson on a client project, I learned that certain documented behaviours and limitations in orjson were going to be road blockers.

Here's a full list of what I learned:

  • Dictionary keys have to be strings. Take a mapping of object ID to some count:

    >>> import json
    >>> json.dumps({1: "one"})
    '{"1": "one"}'
    
    >>> import orjson
    >>> orjson.dumps({1: "one"})
    Traceback (most recent call last):
      ...
    TypeError: Dict key must be str
    

    JSON objects can only have string keys, so the standard library coerces non-string keys with str(). But orjson refuses to do so, with the justification that the coercion is lossy and the keys will come back as strings when deserialized. Thankfully orjson does have an option here, OPT_NON_STR_KEYS, that opts in to the standard library behaviour, but you gotta know about it!

  • Integers are limited to 64 bits.

    >>> json.dumps(2**64)
    '18446744073709551616'
    
    >>> orjson.dumps(2**64)
    Traceback (most recent call last):
      ...
    TypeError: Integer exceeds 64-bit range
    

    JSON itself sets no limit on number sizes, but RFC 8259 warns that implementations may, and many do-JavaScript, for one, silently loses precision beyond 253. orjson caps integers at 64 bits, matching native integer types, while Python's arbitrary-precision integers mean the standard library will happily emit larger values.

    In this case, orjson is probably more correct, but it is lacking an option to restore compatibility if required. (I didn't encounter any use case for massive numbers myself.)

  • There's nowhere to report problems.

    The orjson README sayeth:

    There is no open issue tracker or pull requests due to signal-to-noise ratio.

    I have plenty of sympathy for that decision, having felt the weight of my own project's issue trackers backing up. But it does mean that when you hit any problems, you can't check whether it's known, follow a fix, or contribute one. Your options are to read the CHANGELOG and hope, or to work around it yourself.

  • No sub-interpreter support, ever.

    The README also says:

    orjson does not and will not support PyPy, embedded Python builds for Android/iOS, or PEP 554 subinterpreters.

    I kinda missed this one when adopting orjson, but for me it's a bit of a concern. I think subinterpreters could support some cool use cases, like fast parallel test runners, and from my experience writing extension packages, support for them does not add much overhead.

    And this is not a soft limitation-you can't even import orjson in a sub-interpreter, let alone serialize anything:

    >>> from concurrent import interpreters
    >>> interp = interpreters.create()
    >>> interp.exec("import orjson")
    Traceback (most recent call last):
      ...
    concurrent.interpreters.ExecutionFailed: ImportError: module orjson.orjson does not support loading in subinterpreters
    

    It's a shame that the orjson maintainer advertises such a hard line here.

  • No free-threading support yet.

    orjson currently publishes no wheels for free-threaded Python, which is now "stable" as of Python 3.14. On a free-threaded build, you're forced to compile the Rust package from source, which is a bit of an adoption blocker for large teams.

  • Pydantic decided against it, on trust grounds.

    Back in 2019, a contributor opened a pull request to use orjson in Pydantic, and Samuel Colvin declined it. His stated reasons were:

    1. orjson's author gives no name or personal details on GitHub.
    2. The author had privately emailed Sam asking for the integration, and he was "surprised and somewhat worried by the hostile response I got when I made his/her request public".
    3. The compiled wheels for the package could potentially contain malicious code, which seems like more of a risk given the author's anonymity.

    He was careful to add: "Let me make it clear: I'm not accusing <the maintainer> of anything, I'm 99% certain that his/her intentions are honourable."

    I have the same feelings, now that I'm aware of all the (public) details of orjson. Pseudonymity is entirely legitimate and plenty of excellent software is written under a handle, and this was seven years ago. But stack it up with the closed issue tracker, and it does mean that installing orjson means trusting a compiled binary from a maintainer who has chosen not to engage in public at all.

msgspec's advantages

msgspec answers the questions raised by the above points against orjson:

  • It handles numerical keys the way the standard library does:

    >>> import msgspec.json
    >>> msgspec.json.encode({1: "one"})
    b'{"1":"one"}'
    
  • It encodes and decodes large integers:

    >>> import msgspec.json
    
    >>> msgspec.json.encode(2**64)
    b'18446744073709551616'
    
    >>> msgspec.json.decode(b"18446744073709551616")
    18446744073709551616
    
  • It has an open issue tracker.

  • msgspec fails to import in sub-interpreters right now, but the issue is being worked on by the maintainer and contributors.

  • msgspec publishes free-threading compatible wheels today.

  • The creator is not anonymous and the project is now maintained by a group in a GitHub organization, featuring at least Nikita Sobolev who I have known online from other open source projects (especially django-stubs).

And most importantly, msgspec's encoding and decoding are in the same performance ballpark as orjson's!

msgspec has standard library incompatibilities too

By the way, msgspec isn't fully compatible with json-here are the differences that I know about.

  1. Non-finite floats are encoded as null rather than the standard library's NaN and Infinity:
>>> json.dumps(float("inf"))
'Infinity'

>>> msgspec.json.encode(float("inf"))
b'null'

I'd call this an improvement, since Infinity isn't valid JSON and other parsers will reject it. But it is a change, so if you rely on round-tripping those values, take note.

  1. msgspec also only coerces keys that are string-like or number-like, so booleans and None are still rejected:
>>> json.dumps({None: "nothing"})
'{"null": "nothing"}'

>>> msgspec.json.encode({None: "nothing"})
Traceback (most recent call last):
  ...
TypeError: Only dicts with str-like or number-like keys are supported

Such keys should be rarer than numbers in practice.

What might come next in django-msgspec

django-msgspec covers the same ground as django-orjson today, but msgspec is a broader library than orjson, so there's more potential for future development.

First, msgspec's typed container class, Struct, lets you decode and validate in a single pass:

>>> import msgspec
>>> class Sale(msgspec.Struct):
...     product_id: int
...     count: int
...
>>> msgspec.json.decode(b'{"product_id": 1, "count": 2}', type=Sale)
Sale(product_id=1, count=2)

>>> msgspec.json.decode(b'{"product_id": "one", "count": 2}', type=Sale)
Traceback (most recent call last):
  ...
msgspec.ValidationError: Expected `int`, got `str` - at `$.product_id`

This could be useful for combining with Django views, DRF parsers, or even forms.

Second, msgspec can serialize and deserialize other data types, so they might be worth integrating.

Happy to take suggestions on the design here, on the issue tracker.

Fin

Please try out django-msgspec today and let me know how it goes.

May all your messages be to specification,

-Adam

08 Aug 2026 2:24am GMT

07 Aug 2026

feedDjango community aggregator: Community blog posts

Issue 349: Django 6.1 and a DSF Executive Director

News

Call for applicants for a Django Executive Director

The DSF is hiring its first Executive Director to run fundraising, operations, staff, and legal/compliance for the Foundation. The role is US-based (no visa sponsorship). Applications (resume, optional cover letter, and a vision statement) are due September 14, 2026.

Django 6.1 released

Django 6.1 introduces model field fetch modes, database-level delete options for ForeignKey.on_delete, and dictionary-based email settings. Django 6.0 is now out of mainstream support and receives security and data loss fixes only until April 2027, so plan your upgrade before then.

Thank you to release manager Jacob Walls and the entire Django team on another happy feature release.


Releases

Django security releases issued: 6.0.8 and 5.2.17

The releases address high-severity spatial lookup flaws that could write files or make network requests, plus denial-of-service risks in language and geometry handling and potential XSS from unsafe admin URLField values. Upgrade to Django 6.0.8 or 5.2.17 as soon as possible.

Python 3.15.0 candidate 1 is here!

Python 3.15.0 candidate 1 is available for testing, giving projects a release candidate against which to check compatibility and build wheels.

Python 3.14.7 and 3.13.15 are now available!

Python 3.14.7 and 3.13.15 are available as bug-fix releases, so update your installations.


Wagtail CMS News

An agent-heavy roadmap for 2026

A standards-based look at what agent readiness requires, without the usual hype.


Sponsored Link

Find and fix Python errors faster - for free - with Honeybadger

When something breaks in production, logs tell you something happened. Honeybadger tells you why.

Honeybadger filters out noise and transforms your Python logs into context-rich issues so you can stop guessing and ship the fix faster.


Django Fellow Reports

Django Fellow Report - Jacob

Highlights this week included clearing release blockers for 6.1 and making the parallel test runner more fault tolerant. That means lots of tickets triaged, reviewed, and authored!

Django Fellow Report - Natalia

This week I prioritized time-sensitive security work 🥷, including finalizing patches, preparing and validating backports, and sending pre-notifications ahead of the release. Alongside that, I focused on Tim's "Sprint quickstart" PR 🏃‍➡️ and attended meetings 🎧. Otherwise, I spent time preparing my DjangoCon US talk (it is coming together well, even if I am a bit wary of expectations around my htmx expertise 🎤).

Django Fellow Report - Sarah

Focus of the week was mostly around helping finalize the security release and reviewing the GSOC Selenium to Playwright migration (which is looking in good shape!).


Articles

Django Claude Skills

Mariatta built a set of Django house rules for Claude to follow in her own projects, covering formatting (black, isort, djlint, flake8), full test coverage as a merge requirement, has_perm() over group-membership checks for permissions, and a single Markdown email template that renders both text and HTML. She's explicit that these are personal conventions, not Django community consensus, and that a project's own style wins when contributing elsewhere. She published it as an Astro static site rather than plain Markdown, since she'd rather read the rules in a browser than as agent-only files.

What I love about Django

The best parts of Django are the ones you stop noticing - a tour of the abstractions that have given Buttondown the most leverage over the years.

Django Doesn't Have to Feel Old: Modernize Your Frontend with Vite

A walkthrough of wiring django-vite into a Django project: hot module replacement so CSS edits show up without a full page reload, explicit imports instead of global script-tag collisions, and a vite_asset template tag that resolves to the dev server or hashed production files depending on DEBUG.

Django 6 isn't a revolution. And that's exactly why I like it.

An experienced developer's take on years of building applications with Django and why the latest update continues a philosophy that many modern frameworks seem to have forgotten.

Python: how time-machine is O(1) where freezegun is O(n)

The comparison explains why time-machine avoids freezegun's O(n) slowdown when mocking dates and times, building on benchmarks that found it 100 to 200 times faster across two project sizes.

Core Dispatch #9

Python 3.15.0 release candidate 1 is out, followed by maintenance releases Python 3.14.7 and 3.13.15. The latest Core Dispatch also tracks two new PEPs entering the queue.

Devtools must be open source

Agents can now rebase your local tweaks against upstream automatically, so personalizing a tool costs a prompt instead of an ongoing maintenance burden. That's the case for why closed-source tools like Claude Code can't be personalized the way open alternatives like Codex or Pi can.


DjangoCon US

Save 10% on DjangoCon US 2026 registration

DjangoCon US 2026 runs August 24 to 28 in Chicago, now under three weeks away. Register through our link to take 10% off. Time is running out to get your ticket. Get yours before they are gone!


Events

Chicago Like a Local: Things to Do During DjangoCon US 2026 (Part 1)

Conference chair Keanya Phelps rounds up Italian beef at Mr. Beef and Al's, ramen and vinyl records at Wax in West Town, shuffleboard at Electric Shuffle, and rooftop lake views at Offshore on Navy Pier. She also flags the free Chicago House Music Festival in Millennium Park, August 27 to 30, which overlaps the last days of the conference.


Django Job Board

A few openings this week, including Django and Python Software Foundation roles.

Executive Director at Django Software Foundation 🆕

Security Developer at Python Software Foundation

Senior Full Stack Engineer at Hive Collective

Senior Backend Engineer at MyOme

Python + TypeScript Engineers at Fusionbox


Videos

PyCon US 2026

PyCon US 2026 videos are up.


Projects

wemake-services/django-modern-rest

Modern REST framework for Django with types and async support!

wsvincent/django-skills

Unofficial Django skills based on Django docs and community best-practices.

07 Aug 2026 3:00pm GMT