Couchbase database backend for Django. Drop-in replacement for SQL databases with full ORM support, plus a standalone Document API.
Project description
django-couchbase-orm
Live Demo: django-couchbase-orm-production.up.railway.app A full Django + Wagtail CMS + DRF beer catalog running on Couchbase Capella. Browse beers, read the blog, or explore the Wagtail admin.
Use Couchbase as your Django database. Drop-in backend for django.db.models.Model plus a standalone Document API for Couchbase-native patterns.
Docs: Database Backend | Document API | Wagtail | Hybrid Architecture | Testing
Two Ways to Use It
1. Django Database Backend
Standard Django models work transparently with Couchbase. Admin, forms, DRF, Wagtail - everything just works.
# settings.py
DATABASES = {
"default": {
"ENGINE": "django_couchbase_orm.db.backends.couchbase",
"NAME": "mybucket",
"USER": "Administrator",
"PASSWORD": "password",
"HOST": "couchbase://localhost",
}
}
DEFAULT_AUTO_FIELD = "django_couchbase_orm.db.backends.couchbase.fields.CouchbaseAutoField"
# models.py - standard Django models, no changes needed
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
author = models.ForeignKey("auth.User", on_delete=models.CASCADE)
published = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
Everything works: makemigrations, migrate, createsuperuser, Django admin, ModelForms, DRF serializers, Wagtail CMS.
2. Document API
For Couchbase-native patterns - subdoc operations, KV fast-path, embedded documents.
# settings.py
COUCHBASE = {
"default": {
"CONNECTION_STRING": "couchbase://localhost",
"USERNAME": "Administrator",
"PASSWORD": "password",
"BUCKET": "mybucket",
}
}
# documents.py
from django_couchbase_orm import Document, StringField, FloatField
class Beer(Document):
name = StringField(required=True)
abv = FloatField()
style = StringField()
class Meta:
collection_name = "beers"
Both APIs can coexist in the same project. They share the same Couchbase connection.
Install
pip install django-couchbase-orm
Requires Python 3.10+, Django 4.2+, Couchbase SDK 4.1+.
Django Backend Features
Everything you'd expect from a Django database backend:
manage.py migratecreates Couchbase collectionsmanage.py createsuperuserworksForeignKey,ManyToManyFieldwith JOINs via N1QLselect_related(),prefetch_related()annotate(),aggregate()withCount,Sum,Avg,Min,MaxQ()objects,F()expressions- All lookups:
exact,icontains,startswith,in,isnull,regex, etc. values(),values_list(),distinct(),only(),defer()bulk_create(),bulk_update()- Django admin: list, add, edit, delete, search
- Django auth: users, groups, permissions
- Django sessions (DB backend)
- ContentTypes framework
- ModelForm, DRF ModelSerializer
- Wagtail CMS (page tree, publishing, admin)
SQL-to-N1QL Translation
The backend transparently handles the differences between SQL and N1QL:
| SQL | N1QL (handled automatically) |
|---|---|
INSERT INTO |
UPSERT INTO (idempotent) |
SUBSTRING(s, pos) |
SUBSTR(s, pos-1) (0-indexed) |
IS NULL |
IS NOT VALUED (handles MISSING) |
CAST(x AS INT) |
TONUMBER(x) |
AUTO_INCREMENT |
Atomic counter (binary.increment) |
| Sequential IDs | CouchbaseAutoField (integer PKs) |
Wagtail Support
Wagtail CMS works fully with the Couchbase backend. See the live demo for a working example.
INSTALLED_APPS = [
...
"wagtail", "wagtail.admin", "wagtail.images",
"wagtail.documents", "wagtail.search",
]
# manage.py migrate - creates all Wagtail collections
# manage.py createsuperuser - create admin user
# Page tree, publishing, editing, images, documents all work
Couchbase Capella (Cloud)
Works with Couchbase Capella out of the box:
DATABASES = {
"default": {
"ENGINE": "django_couchbase_orm.db.backends.couchbase",
"NAME": "my-bucket",
"USER": "dbuser",
"PASSWORD": "dbpassword",
"HOST": "couchbases://cb.xxxxx.cloud.couchbase.com",
}
}
Document API Features
For when you need Couchbase-native performance:
- KV-optimized
get(pk=...)(~1ms vs ~50ms for N1QL) - Sub-document operations (partial reads/writes)
- Embedded documents
- Django-style QuerySet with N1QL
- Signals:
pre_save,post_save,pre_delete,post_delete - Async support (
asave,adelete,alist,acount) - Custom migrations framework (
cb_makemigrations,cb_migrate)
Quick Example
from django_couchbase_orm import Document, StringField, FloatField, Q
# CRUD
beer = Beer(name="IPA", abv=6.5, style="IPA")
beer.save()
beer = Beer.objects.get(pk="beer-id") # fast KV lookup
beer.abv = 7.0
beer.save()
beer.delete()
# Queries
Beer.objects.filter(style="IPA", abv__gte=6.0).order_by("-abv")[:20]
Beer.objects.filter(Q(style="IPA") | Q(style="Pale Ale")).count()
Beer.objects.aggregate(avg_abv=Avg("abv"), total=Count("*"))
# Sub-document operations
beer.subdoc.upsert("ratings.average", 4.5)
beer.subdoc.increment("view_count", 1)
beer.subdoc.array_append("tags", "hoppy")
Configuration
Database Backend (recommended)
DATABASES = {
"default": {
"ENGINE": "django_couchbase_orm.db.backends.couchbase",
"NAME": "mybucket", # Couchbase bucket
"USER": "Administrator",
"PASSWORD": "password",
"HOST": "couchbase://localhost",
"OPTIONS": {
"SCOPE": "_default", # optional
},
}
}
DEFAULT_AUTO_FIELD = "django_couchbase_orm.db.backends.couchbase.fields.CouchbaseAutoField"
Document API
COUCHBASE = {
"default": {
"CONNECTION_STRING": "couchbase://localhost",
"USERNAME": "Administrator",
"PASSWORD": "password",
"BUCKET": "mybucket",
"SCOPE": "_default",
}
}
If you use the database backend, the Document API auto-derives its config from DATABASES - no need to set both.
Fields (Document API)
| Field | Type | Options |
|---|---|---|
StringField |
str |
min_length, max_length, regex |
IntegerField |
int |
min_value, max_value |
FloatField |
float |
min_value, max_value |
BooleanField |
bool |
|
UUIDField |
uuid.UUID |
auto=True |
DateTimeField |
datetime |
auto_now, auto_now_add |
DateField |
date |
auto_now, auto_now_add |
ListField |
list |
field for typed elements |
DictField |
dict |
|
EmbeddedDocumentField |
nested | |
ReferenceField |
FK-like |
Known Limitations
- Transactions: Couchbase ACID transactions require multi-node clusters.
atomic()runs as a no-op on single-node setups. - Window functions: N1QL doesn't support
OVER()clauses. - Page moves: Wagtail page tree moves use raw SQL with reserved words. Use delete + recreate as a workaround.
- Correlated subqueries with GROUP BY: Some complex query patterns return empty results gracefully instead of crashing.
- Multi-table inheritance: Works but may have performance implications with N1QL JOINs.
Tests
928+ tests across 38 test modules, tested on Python 3.10 - 3.13.
| Suite | Tests | What's Covered |
|---|---|---|
| Document API | 784 | Fields, QuerySet, Manager, Document CRUD, signals, pagination, migrations, auth, sessions |
| Backend Phase 1 | 57 | Connection, cursor, CRUD, admin login, content types |
| Backend Phase 2 | 37 | FK JOINs, M2M, annotate, lookups, F/Q expressions |
| Backend Phase 3 | 23 | Django admin, auth permissions, forms, sessions |
| Backend Phase 4 | 18 | Migrations, schema ops, custom models |
| Backend Phase 5 | 21 | Shared connections, subqueries, bulk ops, edge cases |
| Security | 27 | Injection prevention, password isolation, backtick escaping |
| Wagtail CRUD | 28 | Page create, publish, edit, unpublish, delete, revisions |
Overall: 91%+ unit test coverage, 0 known vulnerabilities (pip-audit clean).
# All tests (requires local Couchbase)
CB_BUCKET=testbucket pytest tests/ -p no:django --ignore=tests/test_wagtail_urls.py
# Document API tests only (no Couchbase required)
pytest tests/ -m "not integration" -p no:django
# Coverage
coverage run -m pytest tests/ && coverage report --show-missing --include="src/*"
Example Project
The example/ directory contains a complete Django + Wagtail + DRF project (BrewSync) deployed at the live demo. It includes:
- Wagtail CMS with HomePage, BlogIndexPage, BlogPage
- Beer catalog with Brewery/Beer models
- DRF REST API (
/api/beers/,/api/breweries/) - Dark brewery theme with search and filtering
- Deployed on Railway with Couchbase Capella
Development
git clone https://github.com/EdikSimonian/django-couchbase-orm.git
cd django-couchbase-orm
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
License
Apache 2.0
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
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_couchbase_orm-1.0.0.tar.gz.
File metadata
- Download URL: django_couchbase_orm-1.0.0.tar.gz
- Upload date:
- Size: 158.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b60101119521f0bea4c0aebae1140f60fe0e9fff3527fcde1b615ac31f2dbba
|
|
| MD5 |
873c5146b1b4eba018ad80e351e79549
|
|
| BLAKE2b-256 |
6d35cf7e93ab4da3f868fbc51616b614e92c2f13a932a124586b7e8674b95dfc
|
Provenance
The following attestation bundles were made for django_couchbase_orm-1.0.0.tar.gz:
Publisher:
publish.yml on EdikSimonian/django-couchbase-orm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_couchbase_orm-1.0.0.tar.gz -
Subject digest:
2b60101119521f0bea4c0aebae1140f60fe0e9fff3527fcde1b615ac31f2dbba - Sigstore transparency entry: 1229624648
- Sigstore integration time:
-
Permalink:
EdikSimonian/django-couchbase-orm@0e0471edfa48b5f2367cefd073d47af77648f6fd -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/EdikSimonian
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0e0471edfa48b5f2367cefd073d47af77648f6fd -
Trigger Event:
release
-
Statement type:
File details
Details for the file django_couchbase_orm-1.0.0-py3-none-any.whl.
File metadata
- Download URL: django_couchbase_orm-1.0.0-py3-none-any.whl
- Upload date:
- Size: 94.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17e0460dec2f9fe060bf7d8a6c0576b046bc934ee59cdcd58054ef68d8105903
|
|
| MD5 |
1afc827264c62d9756e55852432d2750
|
|
| BLAKE2b-256 |
b95841b207caa98f4b4846abf1b230b8be0560161a6188716cdf8e0fd9401c07
|
Provenance
The following attestation bundles were made for django_couchbase_orm-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on EdikSimonian/django-couchbase-orm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_couchbase_orm-1.0.0-py3-none-any.whl -
Subject digest:
17e0460dec2f9fe060bf7d8a6c0576b046bc934ee59cdcd58054ef68d8105903 - Sigstore transparency entry: 1229624686
- Sigstore integration time:
-
Permalink:
EdikSimonian/django-couchbase-orm@0e0471edfa48b5f2367cefd073d47af77648f6fd -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/EdikSimonian
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0e0471edfa48b5f2367cefd073d47af77648f6fd -
Trigger Event:
release
-
Statement type: