💼 SaaS Features Overview¶
Django Keel includes a complete, production-ready SaaS stack when you select project_type: saas or manually enable SaaS features.
What's Included¶
🏢 Teams & Organizations¶
Full multi-tenancy with role-based access control (RBAC).
- Roles: Owner, Admin, Member
- Team Invitations: Email-based with secure tokens
- Per-Seat Billing: Automatic Stripe quantity updates
💳 Stripe Integration¶
Production-ready subscription billing with two modes.
Basic Mode (stripe API): - Simple subscription flows - Webhook handlers - Customer portal
Advanced Mode (dj-stripe): - Full subscription management - Per-seat and usage-based billing - Subscription metadata - Comprehensive webhook coverage - Customer portal integration
🔒 Feature Gating¶
Control access to features based on subscription plans.
@subscription_required()- Require active subscription@feature_required("advanced_reports")- Check for specific features@plan_required("pro", "enterprise")- Enforce plan tiers- Usage limit checking
- Class-based view mixins
👤 User Impersonation¶
Staff can impersonate users for debugging and support.
- Secure impersonation flow
- Full audit logging
- Middleware integration
- View helpers
- Security checks
🚩 Feature Flags¶
A/B testing and gradual feature rollouts with django-waffle.
- Flags: Boolean on/off per user
- Switches: Global on/off
- Samples: Percentage-based rollouts
- User/group targeting
- Template tags and decorators
Quick Start¶
1. Generate SaaS Project¶
Select saas as project type:
2. Run Migrations¶
This creates all SaaS tables:
- teams_team
- teams_teammember
- teams_teaminvitation
- djstripe_* (if advanced mode)
- waffle_* (feature flags)
3. Create Superuser¶
4. Configure Stripe¶
Add to .env:
# Stripe Keys (get from https://dashboard.stripe.com/test/apikeys)
STRIPE_TEST_PUBLIC_KEY=pk_test_...
STRIPE_TEST_SECRET_KEY=sk_test_...
# Webhook secret: STRIPE_WEBHOOK_SECRET (basic mode)
# or DJSTRIPE_WEBHOOK_SECRET (advanced mode)
DJSTRIPE_WEBHOOK_SECRET=whsec_...
# Stripe Configuration
STRIPE_LIVE_MODE=False
5. Set Up Webhooks¶
Start server:
Use Stripe CLI to forward webhooks:
6. Create Products & Prices¶
In Stripe Dashboard or via Django admin:
Architecture¶
Database Schema¶
erDiagram
User ||--o{ TeamMember : "belongs to"
Team ||--o{ TeamMember : "has"
Team ||--o{ TeamInvitation : "sends"
Subscription ||--o| SubscriptionMetadata : "has"
Team ||--o{ SubscriptionMetadata : "billed for"
User {
int id
string email
string name
}
Team {
int id
string name
string slug
int owner_id
boolean is_active
}
TeamMember {
int id
int team_id
int user_id
string role
boolean is_active
}
TeamInvitation {
int id
int team_id
string email
string role
string token
string status
}
SubscriptionMetadata {
int id
int subscription_id "OneToOne to dj-stripe Subscription"
int team_id "nullable, set when Teams enabled"
json features
json usage_limits
json current_usage
}
Request Flow¶
- User requests feature
- Middleware checks team membership
- Decorator checks subscription status
- Feature gating validates access
- View processes request
- Response returned
Event Flow¶
sequenceDiagram
participant U as User
participant A as App
participant S as Stripe
participant W as Webhook
participant D as Database
U->>A: Subscribe to plan
A->>S: Create subscription
S->>A: Return subscription ID
A->>D: Create subscription record
S->>W: Send webhook event
W->>D: Update subscription status
W->>A: Update features/limits
A->>U: Show success
Configuration¶
Enable SaaS Features¶
In copier.yml answers or during generation:
# Core SaaS
project_type: saas
use_teams: true
use_stripe: true
stripe_mode: advanced
# Optional
use_2fa: true # Two-factor auth
observability_level: full # Full monitoring
security_profile: strict # Enhanced security
Settings¶
Django Keel automatically configures:
Installed Apps:
Middleware:
MIDDLEWARE = [
"apps.users.impersonation.ImpersonationMiddleware",
"waffle.middleware.WaffleMiddleware",
]
URLs:
urlpatterns = [
path("teams/", include("apps.teams.urls")),
path("billing/", include("apps.billing.urls")),
]
Real-World Example¶
Startup SaaS Platform¶
# copier.yml answers
project_type: saas
project_name: AcmeAnalytics
use_teams: true
use_stripe: true
stripe_mode: advanced
use_2fa: true
api_style: both # DRF + GraphQL
frontend: nextjs
background_tasks: celery
use_channels: true # Real-time dashboards
observability_level: full
deployment_targets: kubernetes
What you get: - Multi-tenant analytics platform - Teams with Owner/Admin/Member roles - Stripe subscriptions (Starter/Pro/Enterprise) - Feature gating (API access, advanced analytics) - User impersonation for support - A/B testing with feature flags - Real-time WebSocket updates - Full observability stack - Production-ready Kubernetes deployment
Usage in Code¶
Protect a view:
from apps.billing.decorators import subscription_required, feature_required
from apps.teams.permissions import TeamMemberRequiredMixin
@subscription_required()
@feature_required("advanced_analytics")
def advanced_report(request):
# Only users with active subscription
# AND 'advanced_analytics' feature can access
return render(request, "reports/advanced.html")
Check team membership:
from django.views.generic import ListView
from apps.teams.permissions import TeamMemberRequiredMixin
# URL pattern must include <slug:team_slug>
class ProjectListView(TeamMemberRequiredMixin, ListView):
# Only team members can access
model = Project
def get_queryset(self):
# self.team is set by the mixin from the URL's team_slug
return super().get_queryset().filter(team=self.team)
Feature flags:
from apps.core.feature_flags import is_feature_enabled
if is_feature_enabled("new_dashboard", user=request.user):
return render(request, "dashboard_v2.html")
else:
return render(request, "dashboard.html")
Testing¶
Django Keel includes comprehensive SaaS tests:
# Run the full test suite
just test
# SaaS tests only
pytest tests/teams tests/billing
# Test coverage
pytest --cov=apps.teams --cov=apps.billing
# Integration tests
pytest tests/test_integration.py -v
Test files included:
- tests/teams/test_models.py - Team, member, invitation tests
- tests/teams/test_views.py - View and permission tests
- tests/billing/test_decorators.py - Feature gating tests
- tests/users/test_impersonation.py - Impersonation tests
- tests/core/test_feature_flags.py - Feature flag tests
- tests/test_integration.py - End-to-end workflows
Next Steps¶
- Teams & Organizations → - Multi-tenancy setup
- Stripe Integration → - Subscription billing
- Feature Gating → - Access control
- User Impersonation → - Support tools
- Feature Flags → - A/B testing