Saas-Base / core /models /base.py
rsnarsna
first commit
667aacd
Raw
History Blame Contribute Delete
2.17 kB
"""
Core abstract base models for the entire SaaS platform.
All application models should inherit from BaseModel or SoftDeleteModel
to ensure consistent UUID primary keys, timestamps, and soft-delete behavior.
"""
import uuid
from typing import Optional
from django.db import models
from django.utils import timezone
class BaseManager(models.Manager):
"""Default manager — returns all rows."""
pass
class ActiveManager(models.Manager):
"""Manager that excludes soft-deleted rows."""
def get_queryset(self) -> models.QuerySet:
return super().get_queryset().filter(deleted_at__isnull=True)
class BaseModel(models.Model):
"""
Abstract base providing UUID primary key and timestamps.
Every model in the project should inherit from this.
"""
id: models.UUIDField = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False,
)
created_at: models.DateTimeField = models.DateTimeField(
default=timezone.now,
editable=False,
)
updated_at: models.DateTimeField = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
ordering = ["-created_at"]
def __str__(self) -> str:
return str(self.id)
class SoftDeleteModel(BaseModel):
"""
Abstract base adding soft-delete capability.
Uses `deleted_at` timestamp instead of hard deletion.
Access `objects` for active-only, `all_objects` for everything.
"""
deleted_at: models.DateTimeField = models.DateTimeField(
null=True,
blank=True,
default=None,
)
objects = ActiveManager()
all_objects = BaseManager()
class Meta(BaseModel.Meta):
abstract = True
def soft_delete(self) -> None:
"""Mark this record as deleted."""
self.deleted_at = timezone.now()
self.save(update_fields=["deleted_at", "updated_at"])
def restore(self) -> None:
"""Restore a soft-deleted record."""
self.deleted_at = None
self.save(update_fields=["deleted_at", "updated_at"])
@property
def is_deleted(self) -> bool:
return self.deleted_at is not None