Skip to main content

🚀 django_resaas

The framework you've been missing for building multi-tenant SaaS apps in Django — without reinventing the wheel on every project.

PyPI Python Django License: MIT Status


If you've ever built a SaaS API in Django, you know the drill: multi-tenancy, per-group and per-branch permissions, soft delete, file uploads, PDF generation, i18n, plan-based billing… all of it again, project after project.

django_resaas solves that part once and for all. It's a framework built on top of Django + DRF that gives any application a production-ready foundation: multi-tenancy, RBAC, smart CRUD, dynamic search, per-client feature modules, and billing — so your team can focus on what actually matters: the business.

pip install django_resaas

Table of contents


🎯 Why it exists

"Building SaaS shouldn't be repetitive."

Every multi-tenant SaaS app ends up needing the same set of building blocks. django_resaas ships them ready-made, tested, and consistent with each other:

Without django_resaas With django_resaas
Multi-tenancy hand-rolled on every project BaseModel already ships entity + branch
Permissions checked manually in every view Automatic RBAC via Entity + Branch + Group
CRUD written from scratch for every resource BaseAPIView gives full CRUD in ~5 lines
Destructive delete with no way back Native soft delete + restore + hard delete
Custom search per endpoint Automatic dynamic search (?search=)
"All or nothing" modules Per-client, per-plan module activation
Translations scattered across the code Central i18n system (DB + lang/ files)

✨ Features

  • 🔐 RBAC — permissions by User + Group + context (Entity/Branch)
  • 🏢 Native multi-tenancy — isolation by Entity and Branch
  • Automatic CRUDBaseAPIView with pagination, ordering, filtering and permissions built in
  • 🔎 Dynamic search — automatic search across text fields and relations
  • ♻️ Soft deletedelete() / restore() / hard_delete() + dedicated managers
  • 🧩 Per-client modules — toggle features on/off without a deploy
  • 💰 SaaS-ready billing — plans → modules → automatic activation per entity
  • 📎 Files & PDF — secure uploads, automatic metadata, PDF generation (WeasyPrint)
  • 🔑 JWT auth + 2FAsimplejwt, OTP (pyotp) and QR codes built in
  • 🌍 Built-in i18n — file-based translations (pt-pt, en-us, es-es, fr-fr) and database-backed
  • 🌐 Dedicated middlewares — tenant context, frontend protection and file access control
  • 💵 Native money support (django-money)

⚙️ Installation & setup

pip install django_resaas
# or, for local development:
pip install -e .
# settings.py
INSTALLED_APPS = [
    ...
    "django_resaas",
    "hr",  # example module included
]

MIDDLEWARE = [
    ...
    "django_resaas.core.middleware.tenant.TenantContextMiddleware",
    "django_resaas.core.middleware.front_end.FrontEndMiddleware",
]
make migrate
make superuser
make run          # http://0.0.0.0:7002

🧠 Architecture

User
 ↓
Person
 ↓
Employee (HR)
 ↓
Entity (tenant)
 ↓
Branch
 ↓
Groups + Permissions

Key concepts:

Concept Role
Entity The tenant — typically the client/company
Branch A unit/location within an Entity
Person Human data (name, email, contacts)
User Authentication
BranchUserGroup Links User + Branch + Group, allowing multiple groups per branch

🧪 Full example in 3 files

Model

from django.db import models
from django_resaas.core.base.models import BaseModel

class Employee(BaseModel):
    person = models.ForeignKey("django_resaas.Person", on_delete=models.CASCADE)
    role = models.CharField(max_length=100)

BaseModel already ships entity, branch, created_at/updated_at, created_by/updated_by and soft delete.

Serializer

from django_resaas.core.base.serializers import BaseSerializer

class EmployeeSerializer(BaseSerializer):
    class Meta:
        model = Employee
        fields = "__all__"

View

from django_resaas.core.base.views import BaseAPIView, registerView

@registerView(module="hr")
class EmployeeView(BaseAPIView):
    queryset = Employee.objects.all()
    serializer_class = EmployeeSerializer

That's enough to automatically get: full CRUD, multi-tenant isolation, permissions, search, soft delete, restore, and protection based on the active module.


🔐 Multi-tenancy & RBAC

Tenant context and permissions travel via headers, resolved by TenantContextMiddleware:

ET → entity_type
E  → entity
S  → branch
G  → group
L  → language
request.entity_id
request.branch_id
request.group_id

If a resource's module isn't active for the Entity, access is blocked automatically — no extra code in the view.


🔁 Soft delete

obj.delete()        # soft delete
obj.restore()       # restore
obj.hard_delete()   # permanently delete
Model.objects           # active only
Model.deleted_objects    # deleted only
Model.all_objects        # everything

🔎 Automatic search & filters

GET /api/employees/?search=john

BaseAPIView automatically searches text fields and relations (ForeignKey), with no per-endpoint configuration required.


🧩 Per-client modules + billing

Each Entity only sees the modules it has activated:

Entity Module Status
Company A HR
Company A CRM

Billing flow:

Plan → plan modules → EntityPlan → automatically activates modules on the Entity
sync_apps_entity(entity)  # syncs modules when the plan changes

🌐 Middlewares

Middleware Responsibility
TenantContextMiddleware Resolves entity, branch, group and language from headers
FrontEndMiddleware Protects access via frontend key and route/HTTP-method permissions
FileAccessMiddleware Controls access to protected files and media

🌍 Internationalization (i18n)

Translations are resolved in cascade — database first, then each app's lang/ files — with automatic caching:

from django_resaas.core.utils.translate import Translate

Translate.tdc(request, "Register")

Languages included out of the box: pt-pt, en-us, es-es, fr-fr.


🛠 CLI / management commands

python manage.py setup             # initial SaaS bootstrap
python manage.py create_entity     # creates a new Entity (tenant)
python manage.py create_root       # creates the root user
python manage.py sync_language     # loads the default languages
python manage.py sync_actions      # syncs views registered in VIEW_REGISTRY
python manage.py check             # validates compliance with the MetanoStack standard

🧰 Tech stack

Layer Technology
Backend Django 5.2 + Django REST Framework
Auth djangorestframework-simplejwt, 2FA (pyotp, qrcode)
Database PostgreSQL (psycopg)
Documents WeasyPrint (PDF), python-barcode
Filtering django-filter
Money django-money
Deployment Gunicorn

📚 Documentation

Full technical documentation lives in docs/:


🚀 Roadmap

  • Stripe integration
  • Billing dashboard
  • Resource auto-router
  • Action auditing
  • Multi-tenant logs
  • Permission cache (Redis)

🤝 Contributing

Pull requests are welcome. For larger changes, please open an issue first to discuss direction.

git clone https://github.com/metanochava/django_resaas.git
cd django_resaas
pip install -e .
make check

📄 License

Distributed under the MIT license.


Made by Metano Chavana

Download files

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

Source Distribution

django_resaas-0.0.433.tar.gz (139.9 kB view details)

Uploaded Source

Built Distribution

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

django_resaas-0.0.433-py3-none-any.whl (223.2 kB view details)

Uploaded Python 3

File details

Details for the file django_resaas-0.0.433.tar.gz.

File metadata

  • Download URL: django_resaas-0.0.433.tar.gz
  • Upload date:
  • Size: 139.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_resaas-0.0.433.tar.gz
Algorithm Hash digest
SHA256 4067ce3340274537ea58d56c91048a985253fb43c4bf5d7a19ed22dcbc3c39f8
MD5 5ae5f92b375188c7b8c0909d6847c069
BLAKE2b-256 7d2a14025eed6697094771970db6c67c76ff222517770b7207f051ba0160f2ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_resaas-0.0.433.tar.gz:

Publisher: publish_pypi.yml on metanochava/django_resaas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_resaas-0.0.433-py3-none-any.whl.

File metadata

  • Download URL: django_resaas-0.0.433-py3-none-any.whl
  • Upload date:
  • Size: 223.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_resaas-0.0.433-py3-none-any.whl
Algorithm Hash digest
SHA256 8000b8582d4fc770d7d3f95aa2255ecbad3542a4a2930a5c4d0c6054f9617ab6
MD5 00373a9b62fa244507aa0f50feeec9ef
BLAKE2b-256 b692a079c22636c237ef1923fe4752879e311ac8adcc9f91fe9b0bf190ca2828

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_resaas-0.0.433-py3-none-any.whl:

Publisher: publish_pypi.yml on metanochava/django_resaas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.0.505

2 files

0.0.504

2 files

0.0.503

2 files

0.0.502

2 files

0.0.501

2 files

0.0.500

2 files

0.0.499

2 files

0.0.498

2 files

0.0.497

2 files

0.0.496

2 files

0.0.495

2 files

0.0.494

2 files

0.0.493

2 files

0.0.492

2 files

0.0.491

2 files

0.0.489

2 files

0.0.488

2 files

0.0.487

2 files

0.0.486

2 files

0.0.485

2 files

0.0.484

2 files

0.0.483

2 files

0.0.482

2 files

0.0.481

2 files

0.0.480

2 files

0.0.479

2 files

0.0.478

2 files

0.0.477

2 files

0.0.476

2 files

0.0.475

2 files

0.0.474

2 files

0.0.473

2 files

0.0.472

2 files

0.0.471

2 files

0.0.470

2 files

0.0.469

2 files

0.0.468

2 files

0.0.467

2 files

0.0.466

2 files

0.0.465

2 files

0.0.464

2 files

0.0.463

2 files

0.0.462

2 files

0.0.461

2 files

0.0.460

2 files

0.0.459

2 files

0.0.458

2 files

0.0.457

2 files

0.0.456

2 files

0.0.455

2 files

0.0.454

2 files

0.0.453

2 files

0.0.452

2 files

0.0.451

2 files

0.0.450

2 files

0.0.449

2 files

0.0.448

2 files

0.0.447

2 files

0.0.446

2 files

0.0.445

2 files

0.0.444

2 files

0.0.443

2 files

0.0.442

2 files

0.0.441

2 files

0.0.440

2 files

0.0.439

2 files

0.0.438

2 files

0.0.437

2 files

0.0.436

2 files

0.0.435

2 files

0.0.434

2 files

This release

0.0.433 This release

2 files

0.0.432

2 files

0.0.431

2 files

0.0.430

2 files

0.0.429

2 files

0.0.428

2 files

0.0.427

2 files

0.0.426

2 files

0.0.425

2 files

0.0.424

2 files

0.0.423

2 files

0.0.420

2 files

0.0.419

2 files

0.0.418

2 files

0.0.417

2 files

0.0.416

2 files

0.0.415

2 files

0.0.414

2 files

0.0.413

2 files

0.0.412

2 files

0.0.411

2 files

0.0.410

2 files

0.0.409

2 files

0.0.408

2 files

0.0.407

2 files

0.0.406

2 files

0.0.405

2 files

0.0.404

2 files

0.0.403

2 files

0.0.402

2 files

0.0.401

2 files

0.0.400

2 files

0.0.399

2 files

0.0.398

2 files

0.0.397

2 files

0.0.396

2 files

0.0.395

2 files

0.0.394

2 files

0.0.393

2 files

0.0.392

2 files

0.0.391

2 files

0.0.390

2 files

0.0.389

2 files

0.0.388

2 files

0.0.387

2 files

0.0.386

2 files

0.0.379

2 files

0.0.378

2 files

0.0.377

2 files

0.0.376

2 files

0.0.372

1 file

0.0.371

1 file

0.0.370

1 file

0.0.369

1 file

0.0.368

1 file

0.0.367

1 file

0.0.366

2 files

0.0.365

2 files

0.0.364

2 files

0.0.363

2 files

0.0.362

2 files

0.0.361

2 files

0.0.360

2 files

0.0.359

2 files

0.0.357

2 files

0.0.356

2 files

0.0.355

2 files

0.0.354

2 files

0.0.352

2 files

0.0.351

2 files

0.0.350

2 files

0.0.349

2 files

0.0.348

2 files

0.0.347

2 files

0.0.346

2 files

0.0.345

2 files

0.0.344

2 files

0.0.343

2 files

0.0.342

2 files

0.0.341

2 files

0.0.340

2 files

0.0.339

2 files

0.0.338

2 files

0.0.337

2 files

0.0.336

2 files

0.0.335

2 files

0.0.334

2 files

0.0.333

2 files

0.0.332

2 files

0.0.331

2 files

0.0.330

2 files

0.0.329

2 files

0.0.328

2 files

0.0.327

2 files

0.0.326

2 files

0.0.325

2 files

0.0.324

2 files

0.0.323

2 files

0.0.322

2 files

0.0.321

2 files

0.0.319

2 files

0.0.318

2 files

0.0.317

2 files

0.0.316

2 files

0.0.315

2 files

0.0.314

2 files

0.0.313

2 files

0.0.312

2 files

0.0.311

2 files

0.0.310

2 files

0.0.309

2 files

0.0.308

2 files

0.0.307

2 files

0.0.306

2 files

0.0.305

2 files

0.0.304

2 files

0.0.303

2 files

0.0.302

2 files

0.0.301

2 files

0.0.300

2 files

0.0.297

2 files

0.0.296

2 files

0.0.295

2 files

0.0.294

2 files

0.0.293

2 files

0.0.292

2 files

0.0.291

2 files

0.0.290

2 files

0.0.289

2 files

0.0.288

2 files

0.0.287

2 files

0.0.286

2 files

0.0.285

2 files

0.0.284

2 files

0.0.283

2 files

0.0.282

2 files

0.0.281

2 files

0.0.280

2 files

0.0.279

2 files

0.0.278

2 files

0.0.277

2 files

0.0.276

2 files

0.0.275

2 files

0.0.274

2 files

0.0.269

2 files

0.0.268

2 files

0.0.266

2 files

0.0.265

2 files

0.0.264

2 files

0.0.263

2 files

0.0.262

2 files

0.0.261

2 files

0.0.260

2 files

0.0.259

2 files

0.0.258

2 files

0.0.257

2 files

0.0.256

2 files

0.0.255

2 files

0.0.254

2 files

0.0.253

2 files

0.0.252

2 files

0.0.251

2 files

0.0.250

2 files

0.0.249

2 files

0.0.248

2 files

0.0.247

2 files

0.0.246

2 files

0.0.245

2 files

0.0.244

2 files

0.0.243

2 files

0.0.242

2 files

0.0.241

2 files

0.0.240

2 files

0.0.239

2 files

0.0.238

2 files

0.0.237

2 files

0.0.236

2 files

0.0.235

2 files

0.0.234

2 files

0.0.233

2 files

0.0.232

2 files

0.0.231

2 files

0.0.230

2 files

0.0.229

2 files

0.0.228

2 files

0.0.227

2 files

0.0.226

2 files

0.0.225

2 files

0.0.224

2 files

0.0.223

2 files

0.0.222

2 files

0.0.221

2 files

0.0.220

2 files

0.0.219

2 files

0.0.218

2 files

0.0.217

2 files

0.0.216

2 files

0.0.215

2 files

0.0.214

2 files

0.0.213

2 files

0.0.211

2 files

0.0.210

2 files

0.0.209

2 files

0.0.208

2 files

0.0.207

2 files

0.0.206

2 files

0.0.205

2 files

0.0.204

2 files

0.0.203

2 files

0.0.202

2 files

0.0.201

2 files

0.0.200

2 files

0.0.199

2 files

0.0.198

2 files

0.0.197

2 files

0.0.196

2 files

0.0.195

2 files

0.0.194

2 files

0.0.193

2 files

0.0.192

2 files

0.0.191

2 files

0.0.190

2 files

0.0.189

2 files

0.0.188

2 files

0.0.187

2 files

0.0.186

2 files

0.0.185

2 files

0.0.184

2 files

0.0.183

2 files

0.0.182

2 files

0.0.181

2 files

0.0.180

2 files

0.0.178

2 files

0.0.177

2 files

0.0.176

2 files

0.0.174

2 files

0.0.173

2 files

0.0.172

2 files

0.0.171

2 files

0.0.170

2 files

0.0.169

2 files

0.0.168

2 files

0.0.167

2 files

0.0.166

2 files

0.0.165

2 files

0.0.164

2 files

0.0.163

2 files

0.0.159

2 files

0.0.158

2 files

0.0.157

2 files

0.0.156

2 files

0.0.155

2 files

0.0.152

2 files

0.0.151

2 files

0.0.150

2 files

0.0.149

2 files

0.0.148

2 files

0.0.147

2 files

0.0.146

2 files

0.0.145

2 files

0.0.144

2 files

0.0.143

2 files

0.0.142

2 files

0.0.141

2 files

0.0.140

2 files

0.0.139

2 files

0.0.138

2 files

0.0.137

2 files

0.0.136

2 files

0.0.135

2 files

0.0.134

2 files

0.0.133

2 files

0.0.132

2 files

0.0.131

2 files

0.0.130

2 files

0.0.129

2 files

0.0.128

2 files

0.0.127

2 files

0.0.126

2 files

0.0.125

2 files

0.0.124

2 files

0.0.123

2 files

0.0.122

2 files

0.0.121

2 files

0.0.120

2 files

0.0.119

2 files

0.0.118

2 files

0.0.117

2 files

0.0.116

2 files

0.0.115

2 files

0.0.114

2 files

0.0.113

2 files

0.0.112

2 files

0.0.111

2 files

0.0.110

2 files

0.0.109

2 files

0.0.108

2 files

0.0.107

2 files

0.0.106

2 files

0.0.105

2 files

0.0.104

2 files

0.0.103

2 files

0.0.102

2 files

0.0.101

2 files

0.0.100

2 files

0.0.99

2 files

0.0.97

2 files

0.0.96

2 files

0.0.94

2 files

0.0.93

2 files

0.0.92

2 files

0.0.91

2 files

0.0.90

2 files

0.0.89

2 files

0.0.88

2 files

0.0.87

2 files

0.0.86

2 files

0.0.85

2 files

0.0.82

2 files

0.0.81

2 files

0.0.80

2 files

0.0.79

2 files

0.0.78

2 files

0.0.77

2 files

0.0.76

2 files

0.0.75

2 files

0.0.74

2 files

0.0.72

2 files

0.0.71

2 files

0.0.70

2 files

0.0.69

2 files

0.0.68

2 files

0.0.67

2 files

0.0.66

2 files

0.0.65

2 files

0.0.64

2 files

0.0.63

2 files

0.0.62

2 files

0.0.61

2 files

0.0.60

2 files

0.0.59

2 files

0.0.58

2 files

0.0.57

2 files

0.0.56

2 files

0.0.55

2 files

0.0.54

2 files

0.0.49

2 files

0.0.48

2 files

0.0.47

2 files

0.0.46

2 files

0.0.45

2 files

0.0.44

2 files

0.0.43

2 files

0.0.42

2 files

0.0.41

2 files

0.0.40

2 files

0.0.39

2 files

0.0.38

2 files

0.0.37

2 files

0.0.36

2 files

0.0.35

2 files

0.0.34

2 files

0.0.33

2 files

0.0.32

2 files

0.0.31

2 files

0.0.30

2 files

0.0.29

2 files

0.0.28

2 files

0.0.27

2 files

0.0.26

2 files

0.0.25

2 files

0.0.24

2 files

0.0.23

2 files

0.0.22

2 files

0.0.21

2 files

0.0.20

2 files

0.0.19

2 files

0.0.18

2 files

0.0.17

2 files

0.0.16

2 files

0.0.15

2 files

0.0.14

2 files

0.0.11

2 files

0.0.10

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page