baseline: 批次A-D 成果 + membership 半成品(测试红)
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""租户范围模型的抽象基类。
|
||||
|
||||
所有业务表都应该继承 TenantScopedModel,自动获得:
|
||||
- tenant_id 外键
|
||||
- org_id 外键(可选,预留多组织)
|
||||
- 标准审计字段(created_at, updated_at, created_by, updated_by, is_deleted)
|
||||
- manager `for_tenant(tenant)` 自动加过滤
|
||||
"""
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
|
||||
class TenantScopedQuerySet(models.QuerySet):
|
||||
def for_tenant(self, tenant):
|
||||
return self.filter(tenant=tenant)
|
||||
|
||||
def for_org(self, org):
|
||||
return self.filter(org=org)
|
||||
|
||||
def active(self):
|
||||
return self.filter(is_deleted=False)
|
||||
|
||||
|
||||
class TenantScopedModel(models.Model):
|
||||
tenant = models.ForeignKey(
|
||||
"core.Tenant",
|
||||
on_delete=models.PROTECT,
|
||||
related_name="+",
|
||||
help_text="所属租户",
|
||||
)
|
||||
org = models.ForeignKey(
|
||||
"core.Org",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.PROTECT,
|
||||
related_name="+",
|
||||
help_text="所属组织(多机构预留)",
|
||||
)
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
created_by = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="+",
|
||||
)
|
||||
updated_by = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="+",
|
||||
)
|
||||
|
||||
# 软删除预留
|
||||
is_deleted = models.BooleanField(default=False)
|
||||
deleted_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
# 扩展 JSON 字段:存自定义属性/第三方对接数据/AI 抽取结果
|
||||
ext_data = models.JSONField(default=dict, blank=True)
|
||||
|
||||
# 来源渠道(预留 AI Agent / 电商对接):manual/api/web/miniprogram/ai_agent
|
||||
source_channel = models.CharField(max_length=32, blank=True, default="manual")
|
||||
|
||||
objects = TenantScopedQuerySet.as_manager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
indexes = [
|
||||
models.Index(fields=["tenant", "-created_at"]),
|
||||
models.Index(fields=["tenant", "is_deleted"]),
|
||||
]
|
||||
Reference in New Issue
Block a user