Django response classes for all RFC9110 HTTP status codes
Project description
django-allresponses
A Django package that provides response classes for all RFC 9110 HTTP status codes.
Features
- Response classes for all RFC 9110 HTTP status codes
- Compatible with Django 4.2 LTS and later versions
- Full test coverage
- Type hints included
Installation
uv add django-allresponses
# or with pip
pip install django-allresponses
Usage
All response classes in this package are subclasses of Django’s
HttpResponse.
You can use them anywhere you would use a normal HttpResponse, and they work
with Django’s middleware and testing tools.
For HTML or other content, use the HttpResponse-prefixed classes:
from django_allresponses import HttpResponseOK, HttpResponseNoContent, HttpResponseCreated
def my_view(request):
# Return a 200 OK response (explicit status)
return HttpResponseOK("<p>Hello</p>")
# Or 204 No Content
return HttpResponseNoContent()
# Or 201 Created with a Location header
return HttpResponseCreated(location='/api/resource/123')
For JSON APIs, use the JsonResponse-prefixed classes (they subclass
Django’s
JsonResponse
and set the status code for you):
from django_allresponses import JsonResponseOK, JsonResponseCreated, JsonResponseUnauthorized
def api_view(request):
if not request.user.is_authenticated:
return JsonResponseUnauthorized({"error": "Authentication required"})
data = {"id": 123, "name": "Example"}
return JsonResponseCreated(data, location="/api/items/123")
Why this package?
Basically, because Django has a whole bunch of custom HttpResponse subclasses, for BadRequest, for ResponseNotFound, for ResponseNotModified and so on.
But for some very standard response codes such as No Content (HTTP 204) and Created (HTTP 201) there are no subclasses. In RESTy systems I use these response codes all the time.
It feels very arbitrary that some classes exist and others don't.
Of course I can make my own subclass and use that but I would like Django to have it built-in. So I opened a discussion about this:
TL;DR: people do not find it is 'worth it' to add these response codes that are used a lot, because you could just as well write your own, or use the 'generic' HTTPResponse and add a custom code.
That's all fair, but I do think that custom classes have other benefits too. I think it's beneficial to list the responses that you can choose from all in one place, instead of having a specific response for Gone (HTTP 410) but none for Created.
So I went all maximalist and added a complete list of all RFC9110 HTTP status codes as subclasses in this django-allresponses module. Many of those will probably never be used at all, which I think is fine, but at least now you'll have one easy way to refer to all possible HTTP responses in one go!
Several subclasses add real behaviour on top of the status code, so they are
not just “a status number in a class”. For example: 204 No Content and
205 Reset Content strip the Content-Type header and forbid setting a
response body; 201 Created requires a location and sets the Location
header; 405 Method Not Allowed requires the list of allowed methods and
sets the Allow header (as required by
RFC 9110); 503 Service
Unavailable accepts an optional retry_after keyword (seconds or a datetime)
and sets the Retry-After header. Using these classes keeps your responses
spec-compliant and consistent. Plus the explicit status names also help with
readability of your code!
One last benefit of using this module is that some HTTP status codes changed name in different RFCs. Django being a seasoned project is using th e 'older' names for HTTP statuses. Our module uses newer names. For example, Django's HttpResponsePermanentRedirect returns a 302 by default but 302 is now "Found". Our HttpResponsePermanentRedirect returns 308, and we also include HttpResponseFound which returns 302 for when you might need it.
Development
This project uses uv for dependency management and hatch for building. A
Makefile wraps the common commands (run make help for a list).
To set up the development environment:
# Install uv if you haven't already
pip install uv
# Create a virtual environment and install dependencies
uv venv
source .venv/bin/activate # On Unix/macOS
# or
.venv\Scripts\activate # On Windows
# Install dependencies
make install
# Or with dev tools (pytest, pdoc, ruff, ty): make install-dev
Running tests
Run from the project root (the directory that contains manage.py and the
Makefile).
make test # Django test runner (no extra deps)
make test-pytest # Pytest (needs: make install-dev)
The test suite uses a minimal Django project under tests/
(tests/settings.py and the tests app). Django needs
DJANGO_SETTINGS_MODULE=tests.settings, which manage.py sets automatically;
pytest uses the same via pyproject.toml.
Building the documentation site
Docstrings on every response class explain when and why to use that status code; they appear in your editor (e.g. hover) and can be turned into a static documentation site with Zensical (MkDocs-compatible) and mkdocstrings.
make install-deps # once: install zensical and other dev deps
make docs # build HTML into site/
make serve-docs # serve docs in the browser at http://localhost:8080
Type checking
Type checking uses ty (Astral’s type checker). Run from the project root (requires dev deps):
make install-dev # once: install ty and other dev deps
make typecheck # uv run ty check .
After make docs, open site/index.html in a browser, or run
make serve-docs to preview with live reload. Source lives in docs/;
Zensical writes the built site to site/ (in .gitignore). The project uses
Zensical (from the Material for MkDocs team), which
reads mkdocs.yml directly. Building
the docs requires Python 3.10+ (the runtime package still supports 3.8+).
License
MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_allresponses-0.1.0.tar.gz.
File metadata
- Download URL: django_allresponses-0.1.0.tar.gz
- Upload date:
- Size: 15.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcb919df1505406f11c50ba5dcab6bac9a8e2e30f360434a66ba71ee0ac15ddc
|
|
| MD5 |
f3c5dceacdf9b00957b9433247fb2804
|
|
| BLAKE2b-256 |
c5d7aefd0a4bf360c97dcac37e6bb031a4838169adf690f0fd8dc8d8ed24ff9e
|
File details
Details for the file django_allresponses-0.1.0-py3-none-any.whl.
File metadata
- Download URL: django_allresponses-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.7 {"installer":{"name":"uv","version":"0.10.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ce5c04154650126035f4c48f771021b08987ab836787c7e9e0a5732e4c0a833
|
|
| MD5 |
70143432063ff26949092ba1c888cbd8
|
|
| BLAKE2b-256 |
758d8677f6aacee412d0cf072fbc045ded8157be4614769995c9a858d976df9e
|