Django-MOJO
The full-stack Django framework for teams that want to ship, not assemble.
Most Django projects end up wiring together the same set of packages: a REST layer, an auth system, a job queue, a WebSocket server, a file store, a secrets manager, a metrics backend. Each one has its own conventions, its own config, its own failure modes — and none of them know about each other.
Django-MOJO ships all of that pre-integrated, with consistent patterns throughout. Define your models, configure permissions, and you have a production-grade API. The rest is already there when you need it.
What You Get
| You used to wire up... | Django-MOJO ships... |
|---|---|
| DRF + serializers + viewsets | Model-first REST with RestMeta — permissions, graphs, filtering, pagination built in |
| SimpleJWT + django-allauth + MFA library | Complete auth stack: JWT, OAuth, TOTP, passkeys, API keys, device management, session control |
| Channels + custom routing | WebSocket pub/sub realtime — same auth as HTTP, topic-based, zero extra config |
| Celery + Redis | Async job queue with scheduling, retries, heartbeat, and a web API |
| django-storages + custom S3 wrappers | File upload, S3 backend, renditions, and an encrypted file vault |
| python-decouple + HashiCorp Vault | DB-backed encrypted settings — secrets stay out of your repo, update without restart |
| structlog + Sentry + custom alerting | Request logging, security incident tracking, and alerting baked into the request cycle |
| InfluxDB client or custom Redis counters | Redis-backed time-series metrics with group-scoped rollups |
| Twilio SDK + phone number logic | PhoneHub — SMS sending, phone normalization, test-number shortcuts |
Install
pip install django-mojo
Quick Start
1. Define your model:
from django.db import models
from mojo.models import MojoModel
class Article(models.Model, MojoModel):
title = models.CharField(max_length=200)
body = models.TextField()
author = models.ForeignKey("account.User", on_delete=models.CASCADE)
is_published = models.BooleanField(default=False)
class RestMeta:
VIEW_PERMS = ["view_articles"]
SAVE_PERMS = ["manage_articles"]
LIST_DEFAULT_FILTERS = {"is_published": True}
GRAPHS = {
"default": {"fields": ["id", "title", "created"]},
"detail": {"fields": ["id", "title", "body", "author", "created"]},
}
LIST_DEFAULT_FILTERS is a baseline, not a cage — a caller naming the same
field (?is_published=false) or passing ?_no_defaults=1 sees the rest. See
Default list filters.
2. Expose it as a REST endpoint:
from mojo import decorators as md
from .models.article import Article
@md.URL('article')
@md.uses_model_security(Article)
def on_article(request, pk=None):
return Article.on_rest_request(request, pk)
That's it. You now have list, retrieve, create, update, and delete — with object-level permissions, graph-controlled output, filtering, pagination, and auth — all from two files.
Authentication Out of the Box
Django-MOJO ships a complete auth stack. Nothing to install or wire up separately.
- JWT — access + refresh tokens, configurable TTLs, device-aware
- OAuth — Google, Apple, and extensible to any provider
- TOTP — authenticator apps, backup codes, recovery flow
- Passkeys — WebAuthn discoverable credentials
- API Keys — per-user, revocable, scoped
- Sessions — list and revoke active sessions
- Security events — login history, suspicious activity, lockout guard
# Login — returns JWT access + refresh tokens
POST /api/account/login
{"username": "user@example.com", "password": "..."}
# All auth flows use the same bearer token middleware
Authorization: Bearer <token>
Secure Settings
Secrets belong in the database, not in your repo. Django-MOJO's settings helper reads from a lookup chain: Redis cache → DB (group-scoped → global) → Django file settings.
from mojo.helpers.settings import settings
# Static config — read from file, safe at import time
HEADER = settings.get_static("DUID_HEADER", "x-mojo-duid")
# Dynamic secrets — read from DB/Redis at call time
def send_sms(to, body):
sid = settings.get("TWILIO_ACCOUNT_SID", kind="str")
token = settings.get("TWILIO_AUTH_TOKEN", kind="str")
...
DB-backed settings activate automatically once Django is ready — no manual flag, no restart required to pick up changes.
Async Jobs
from mojo.apps.jobs import queue_job
# Queue a background task
queue_job("send_welcome_email", user_id=user.pk)
# Define the handler
from mojo.apps.jobs import job_handler
@job_handler("send_welcome_email")
def handle_welcome_email(job):
user = User.objects.get(pk=job.data["user_id"])
...
Built-in: priority channels, retries with backoff, idempotency keys, scheduled jobs, worker heartbeat, and a REST API for job status.
Realtime WebSockets
# Client subscribes to a topic
ws.send({"action": "subscribe", "topic": "user:123"})
# Server pushes to a topic from anywhere
from mojo.apps.realtime import publish
publish("user:123", {"type": "notification", "message": "You have a new message"})
Same JWT authentication as HTTP. No extra config.
Project Layout
mojo/
├── apps/
│ ├── account/ # Users, groups, auth (JWT, OAuth, TOTP, passkeys, API keys)
│ ├── jobs/ # Async job queue and scheduler
│ ├── realtime/ # WebSocket pub/sub (Django Channels)
│ ├── fileman/ # File upload, S3 backend, renditions
│ ├── filevault/ # Encrypted file vault
│ ├── logit/ # Request + database logging
│ ├── incident/ # Security incident tracking and alerting
│ ├── metrics/ # Redis-backed time-series metrics
│ ├── phonehub/ # SMS and phone number management
│ ├── shortlink/ # URL shortening
│ ├── docit/ # Wiki and documentation pages
│ └── aws/ # SES email, SNS, S3 helpers
├── helpers/
│ ├── settings/ # DB-backed settings with encryption
│ ├── crypto/ # Signing, hashing, token generation
│ ├── logit/ # Structured logging
│ ├── geoip/ # IP geolocation and threat detection
│ ├── content_guard/ # Deterministic content moderation
│ └── ... # dates, redis, request, response, paths, and more
├── middleware/ # CORS, auth, request logging
├── models/ # MojoModel, RestMeta base classes
├── serializers/ # Serialization engine and cache
└── rest/ # OpenAPI, decorators, routing
Documentation
Docs are organized by audience and optimized for both human developers and AI coding assistants.
Django Developer Reference
For developers building applications with Django-MOJO.
| Section | Description |
|---|---|
| Core | MojoModel, REST framework, decorators, middleware, serialization |
| Helpers | logit, dates, settings, crypto, request, redis, and other utilities |
| Account | User, Group, JWT auth, OAuth, TOTP, passkeys, API keys, sessions |
| Logging | Database logging, security incidents |
| Fileman | File upload, storage backends, renditions |
| AWS SES email, templates, inbound handling | |
| Jobs | Async task queue |
| Metrics | Redis-backed time-series metrics |
| Realtime | WebSocket pub/sub |
| PhoneHub | Phone number management and SMS |
| FileVault | Encrypted file vault |
| DocIt | Documentation and wiki system |
REST API Reference
For frontend and mobile developers integrating with Django-MOJO APIs.
| Section | Description |
|---|---|
| Core | Authentication, request format, filtering, pagination, graphs |
| Account | Login, users, groups, API keys |
| Logging | Log queries, incident management |
| Fileman | File uploads and downloads |
| Templates, mailboxes | |
| Jobs | Job status |
| Metrics | Time-series metrics |
| Realtime | WebSocket protocol |
| PhoneHub | Phone lookup and normalization |
| FileVault | Encrypted file vault |
| DocIt | Documentation pages |
Migrating from django-nativemojo
If you currently have django-nativemojo installed, switch with no code changes — your imports are unchanged.
pip uninstall django-nativemojo
pip install django-mojo
The old package name remains available as a compatibility shim for existing deployments.
Contributing
Pull requests and issues are welcome. Contributions should follow the Developer Guide and keep to the framework's philosophy: explicit over magic, secure by default, conventions over configuration.
License
Licensed under the MIT License. See LICENSE for details.
Release files for django-mojo 1.24.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_mojo-1.24.12.tar.gz | 7.9 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_mojo-1.24.12-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.3 MB
Release files / django_mojo-1.24.12.tar.gz
| Download URL | django_mojo-1.24.12.tar.gz |
|---|---|
| Size | 7.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4062bca7ce5c58574f4e5e30ddd510d6f7f7f5fa895ad650642692600fea2d1d
|
|
BLAKE2b-256 checksum How to use checksums |
b325479e24c74a75463b090c28bfe1b1947723d0322cacfad33d001bcf95e914
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / django_mojo-1.24.12-py3-none-any.whl
| Download URL | django_mojo-1.24.12-py3-none-any.whl |
|---|---|
| Size | 4.4 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
24f9789b2da90e7740221abacca7e712277279eeb04c9443abdd5b3ab66de4b5
|
|
BLAKE2b-256 checksum How to use checksums |
a1a06f030c98da6f24a38a6415a18789f8c018e526696c6c5a74ffa624b71711
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|