Skip to main content

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:

https://forum.djangoproject.com/t/proposal-or-discussion-add-subclasses-for-no-content-and-created-httpresponses/39020

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_allresponses-0.1.0.tar.gz (15.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_allresponses-0.1.0-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

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

Hashes for django_allresponses-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bcb919df1505406f11c50ba5dcab6bac9a8e2e30f360434a66ba71ee0ac15ddc
MD5 f3c5dceacdf9b00957b9433247fb2804
BLAKE2b-256 c5d7aefd0a4bf360c97dcac37e6bb031a4838169adf690f0fd8dc8d8ed24ff9e

See more details on using hashes here.

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

Hashes for django_allresponses-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1ce5c04154650126035f4c48f771021b08987ab836787c7e9e0a5732e4c0a833
MD5 70143432063ff26949092ba1c888cbd8
BLAKE2b-256 758d8677f6aacee412d0cf072fbc045ded8157be4614769995c9a858d976df9e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page