15 Sep 2026

feedDjango community aggregator: Community blog posts

Duff's device, part 2: copying within an array

Duff's device in JavaScript raced hand-written loops that copy one array into another. A reader asked the follow-up: how do they compare with Array#copyWithin, the built-in that copies a range inside a single array? That is a different workload, so it needs its own measurement. The short answer: on every Node and Deno we can install today, the built-in runs 47 to 84 times slower than the loop.

Duff’s device, part 2: copying within an array

15 Sep 2026 10:00am GMT

Django: introducing django-mcpz, for making MCP servers

I made another package! Say hello to django-mcpz, for building Model Context Protocol (MCP) servers in your Django project.

The package tagline is easy peasy MCP servers in Django.

MCP, the place to be?

MCP specifies a way for LLMs to interact with external data sources. MCP servers can expose a set of tools, which are essentially functions that an LLM can call on behalf of a user. So, for example, a user can ask "where's my pizza at?" and the LLM can call one or more tools on your pizza shop server to navigate your data and return the answer. Users can ask questions in natural language, and LLMs can interpret messy data in your system to return a clean, hopefully-correct answer.

MCP is date-versioned, and the latest version, 2026-07-28, made the protocol much simpler by making it stateless, like ye olde HTTP APIs. There's no longer an initialization handshake, no session ID, and no streaming event stream. Each request is a plain HTTP POST with a JSON body that gets one JSON response, like any other HTTP API.

This new version is way easier to deploy for a typical synchronous, WSGI Django project. The previous default transport required the server to hold open streaming responses (server-sent events) and track sessions, which would entail a separate ASGI deployment using Channels. Now, you can make an MCP server within a single synchronous Django view and keep it inside your normal WSGI deployment, no extra infrastructure required.

One of my clients wants to deploy an MCP server for their app, and so I took it upon myself to take advantage of this new MCP version and build a ground-up implementation, rather than use the existing ASGI-based packages. The goal was to make it "easy peasy" to build an MCP server in your Django project, and so I named it django-mcpz ("pz" read in the American way is "pea-zee", as in "easy peasy") (or maybe I should stick to calling it "pea-zed"?).

django-mcpz targets the latest MCP version, 2026-07-28, with its stateless-by-default transport, but it still works with last year's 2025 versions too, which also had a stateless mode. Client support seems widespread, and anyway, this is an ecosystem that moves fast.

The basics

Here's the example from the README, a server for a shop with one tool that counts orders:

from typing import Literal

import msgspec

from django_mcpz.server import MCPServer
from django_mcpz.bearer_tokens.auth import token_auth
from example.models import Order

server = MCPServer(
    name="shop",
    version="1.0.0",
    instructions="Query the shop's order database.",
    auth=token_auth,
)


class CountOrdersParams(msgspec.Struct):
    status: Literal["pending", "shipped", "cancelled"] | None = None


class CountOrdersResult(msgspec.Struct):
    count: int


@server.tool(
    description="Count Order rows, optionally filtered by status.",
    read_only=True,
)
def count_orders(request, params: CountOrdersParams) -> CountOrdersResult:
    qs = Order.objects.all()
    if params.status is not None:
        qs = qs.filter(status=params.status)
    return CountOrdersResult(count=qs.count())

Some notes:

  • MCPServer represents one server and its registry of tools. It works a bit like Django's admin.site: you create one, register things on it, and route it like a plain old view function. The instructions are natural-language guidance for the LLM on how to use the server.
  • The auth argument is required, since an MCP server exposes your application's internals to network callers. More on that below.
  • server.tool() registers a plain function as a tool. The function receives the HttpRequest first, then its parameters, and Django's request/response cycle applies as usual, so it can use the ORM, request.user, and anything else a view can.
  • Parameters and results are declared as msgspec Struct classes. django-mcpz generates the tool's JSON Schemas from the type annotations, and validates each call's arguments before the tool runs. Mistyped or unknown arguments are rejected with in-band errors that the calling LLM can read and correct from. msgspec also handles all the JSON serialization and deserialization, via my recently-released django-msgspec, so it's fast.
  • read_only=True sets one of the specification's tool annotations, hints for client user interfaces about what a tool does. For example, an UI might not prompt for confirmation before calling a read-only tool, but it will for a write tool.

The server is its own view function, so you route it directly in your urls.py:

from django.urls import path

from example.mcp import server

urlpatterns = [
    path("mcp", server),
]

And that's all! Deploy as normal, and your MCP server is live at /mcp.

My editor, Zed, has MCP support. I hooked it up to a test project running the above server code and had this brief conversation with an LLM:

## User

count the number of orders in my shop

## Assistant

<thinking>
This "shop" order counting tool has nothing to do with the actual blog project, so it looks like an unrelated test scenario. I'll just go ahead and use the tool as requested.


</thinking>

**Tool Call: Run MCP tool `count_orders`**
Status: Completed

{"count":42}

## Assistant

Your shop has **42 orders** in total.

The LLM detected the "shop" as unrelated to my blog and guessed it was just a test. Well played.

Everything else talking MCP should "just work" too, including Claude Code and Codex.

Authentication

Every server needs an auth callable, which runs before the request body is touched. It receives the request and returns None to allow it, or an HttpResponse to reject it. There's a public callable for servers protected some other way, or that are genuinely public, and you can write your own for, say, an authenticating reverse proxy. But the two common cases are covered by optional apps within django-mcpz.

Developer tools, like Claude Code, Codex, and Cursor, accept a pasted credential in their configuration. For them, there's the django_mcpz.bearer_tokens app, which provides per-client bearer tokens, each acting as a user, and revocable one at a time. Add it to INSTALLED_APPS, run migrate, and pass its token_auth callable to your server, as in the example above. Then create tokens with a management command, which prints the token value once:

$ python manage.py mcpz bearer-tokens create "Claude Code" --user alice
...

…or in the admin. Only a hash of each token is stored, like Django does for passwords, so a leaked database dump does not reveal usable credentials.

Hosted assistants, like Claude.ai and ChatGPT, offer no way to enter a header when adding a server. They connect through OAuth: the user clicks "connect", logs in to your site, approves access, and the assistant receives tokens to call your server with. For these assistants, there's the django_mcpz.oauth app, an authorization server built into your project, implementing the MCP authorization specification and the OAuth standards it draws on. Add the app, include its URLs, and pass its oauth_auth callable to your server:

from django.urls import include, path

from example.mcp import server

urlpatterns = [
    path("mcp", server),
    path("oauth/", include("django_mcpz.oauth.urls")),
    path("", include("django_mcpz.oauth.wellknown")),
]

The app reads everything it needs from your URLconf and each request, so there's nothing else to configure. It ships with a consent page, rendered from templates you can override to match your site, and admin pages for managing clients and tokens. To serve both kinds of client from one server, combine the two callables in a few lines, as covered in the docs.

MCPizza

The django-mcpz repository contains an example project that serves a local MCP server for a pizza place called MCPizza (not to be confused with McPizza). It has tools to check today's date, search the menu, place an order, chart today's orders as an image, and link to the menu web page.

The example is intended to show a use case that allows an LLM to make decisions based on freeform text in a database. Each pizza has structured fields the server enforces, such as price and the dates a special runs between, as well as freeform notes that an LLM can act on, such as "Vegan cheese available on request".

Here's an example from the README, using Claude Code to query the server, calling the current_date and search_menu tools:

$ claude --mcp-config mcp.json --strict-mcp-config --allowedTools "mcp__mcpizza__*" \
  -p "What vegetarian pizzas could I order tomorrow for under \$12? I'd prefer vegan if they can do it."
For tomorrow (2026-09-04), the vegetarian options under $12 are:

- **Null Pointer** - $6 - plain base, vegan by default (no cheese/toppings)
- **Garlic Bread (Technically a Pizza)** - $5.50 - vegetarian; GF base available, but not noted as vegan-adaptable
- **Margherita of Theseus** - $9.50 - vegetarian, **vegan cheese available on request**
- **The Off-By-One** (mushrooms, olives, red onion) - $10.50 - vegetarian, **vegan cheese available on request**

Since you'd prefer vegan: **Margherita of Theseus** or **The Off-By-One** both work with vegan cheese swapped in, and **Null Pointer** is vegan as-is (though it's just a plain base). Want me to place an order for one of these?

The README also covers querying it with the llm CLI and the official MCP Python SDK. Give it a whirl and inspect the code to learn more!

Future workings

django-mcpz implements MCP Tools (callable functions), since that's what most Django projects need. There are other parts of the protocol that it might gain, depending on demand:

  • Elicitations - server-generated questions for users to answer, that can guide your tool to the right data.
  • Prompts - text templates to guide LLMs in using your server for particular tasks.
  • Resources - API-like data access, for LLMs to query your server's data directly, rather than through tools.

There's no plan at current for django-mcpz to implement streaming events or async support, since the goal for the package is a simpler implementation that fits the typical Django deployment.

Fin

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

May your MCP be as EZ as 123,

-Adam

15 Sep 2026 4:00am GMT

11 Sep 2026

feedDjango community aggregator: Community blog posts

Issue 354: DjangoCon US Recaps and the Myth of the Well-Structured Project


News

PyCharm & Django Fundraiser Extended to September 14

The second half of our annual JetBrains fundraiser has been extended through September 14, 2026. Thank you to JetBrains for the extra time. You still have time to renew your PyCharm license or give it a try.

Call for volunteers: Fundraising Working Group

The Django Software Foundation is looking for people to join the Fundraising Working Group. This is a particularly interesting time to get involved.


Django Software Foundation

Django Steering Council Meetings - 2026

Notes from the September 7 meeting: packaging related tools as extras, experimental features, usage telemetry, and Fellows pinging the CompositeField and content type parsing DEPs.


Python Software Foundation

Incident Report: File Hosting Errors

Two weeks of intermittent 502s and 503s on files.pythonhosted.org came from a Fastly canary that left one cache node half rolled back, which then exposed three latent bugs in PyPI's own config. The takeaway for the rest of us: turn on dependency caching in CI, which setup-python leaves off by default.


Wagtail CMS News

Prototyping a new CLI for Wagtail

Thibaud Colas is prototyping wagtail-cli, a terminal interface over the v3 API for browsing and publishing pages, managing media, and scaffolding projects, partly so AI agents can reach the CMS without driving a browser. Try it with uv tool install wagtail-cli.


Updates to Django

Today, "Updates to Django" is presented by Raffaella from Djangonaut Space! πŸš€

Last week we had 15 pull requests merged into Django by 12 different contributors - including 2 first-time contributors! Congratulations to Vimal Sahani and Dave Gaeddert for having their first commits merged into Django - welcome on board!

News in Django 6.1:

News in Django 6.2:


Django Fellow Reports

Django Fellow Report - Jacob

An early report for about a day at my desk before heading out for some vacation. Six tickets reviewed, two authored, and the usual misc.

Django Fellow Report - Sarah

Seven tickets reviewed and another seven authored. Fellows sync, engaging with security issues, and website working group meeting.

Django Fellow Report - Natalia

Post-DjangoCon US week (including the emotional low πŸ’” that comes with it), with most of my time going into two things: first, iterating on a security report until we could confirm the issue, followed by developing a solution for it. I also continued the calendar versioning work around DEP 20 πŸ“…, including both the Django implementation and the release process updates. And, after iterating on a PR tutorial since Vigo, I finally got to see it through.


Sponsored

Your task ran before the transaction committed.

django-ox is a production worker for Django Tasks that runs on the database you already have: no Celery, no Redis, no broker to babysit. Enqueue is a plain INSERT, so a task commits or rolls back with the data it belongs to. Django 5.2 LTS and 6.x, free, BSD-3.


Articles

Soft-deprecating re.match()

After 30 years of tripping people up by anchoring at the start of a string but not the end, re.match() is soft-deprecated in Python 3.15 in favor of the clearer re.prefixmatch().

1001 Django apps - The myth of a well-structured Django project

Ronny Vedrilla makes a thoughtful case for fewer Django apps: treating them as database namespaces rather than folders, starting with one domain plus a few "satellite" apps, and using import-linter to enforce the boundaries so they don't just become decoration.

Nifty Django Feature: Q() Objects

Assigning Q() objects to named variables makes filter logic readable and reusable, and passing several into one .filter() call avoids the extra joins you get from chaining.


DjangoCon US Recaps

I Think That Feeling is Called Hope - Rachell Calhoun

Rachell Calhoun's DjangoCon US recap comes from inside the machinery: a third year chairing volunteers alongside Monica Oyugi, the first time all five Djangonaut Space founders stood in the same room, and open spaces on contributing to Django and on music. It ends on the case for volunteering, which she calls the fastest way she knows to stop feeling like a stranger at a conference.

TSBT73: Pumpkin Spice Bytes - Velda Kiara

Velda Kiara's update on DjangoCon US and related tech discoveries.

The Community Behind Django: My First DjangoCon US Recap and Highlights - Seyram Theresa

Theresa's very in-depth recap of DjangoCon US, from talks and keynotes to lightning talks, hallway convos, Chicago adventures, and more.

DjangoCon US 2026 | Chicago - Jon Gould

Recruiter Jon Gould's fourth DjangoCon, from the sponsor side of the table. His favorite parts were the unscheduled ones, like Aman Singh's early morning walks to the Bean.

Your City Is a Spatial Database and Nobody Told You - Jason Judkins

Jason Judkins's recap of a specific talk at DjangoCon US the other week, by Drishti Jain, highlighting how important shapes and GeoDjango are in the real world.


Django Job Board

Two construction-AI roles at Provision and a backend seat on the platform that runs a family-owned cruise agency.

πŸ†• Machine Learning Engineer (Hybrid) at Provision

Django Developer at The Cruise Brothers

Full Stack Software Engineer (Hybrid) at Provision


Projects

gettranslatebot/translatebot-django

Translates .po files and model fields with an LLM, but only the new and changed strings, using a TRANSLATING.md glossary in your repo to keep terminology consistent between runs. Placeholders and HTML tags survive intact.

lincolnloop/django-absurd

Plugs Absurd, a Postgres-native workflow engine, into Django's Tasks framework so background tasks and durable workflows run on the database connection you already have. Needs Django 6.0+ and psycopg 3.

11 Sep 2026 3:00pm GMT