Django DRF B2B应用发布及草稿保存功能实现方案咨询
Django Rest Framework 实现仪表盘草稿/发布功能方案
1. 数据库模型设计
这是功能的核心基础,采用单表版本化设计兼容草稿、已发布配置的存储,同时支持历史版本追溯:
from django.db import models from django.contrib.auth import get_user_model User = get_user_model() class Company(models.Model): # 企业基础信息,已有则不需要额外定义 name = models.CharField(max_length=128) # 其他企业字段省略 class DashboardConfig(models.Model): STATUS_CHOICES = ( ("draft", "草稿"), ("published", "已发布"), ) company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name="dashboard_configs") created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="dashboard_drafts") # 存储所有仪表盘配置,比如布局、筛选条件、显示维度等 config_content = models.JSONField() status = models.CharField(max_length=16, choices=STATUS_CHOICES, default="draft") # 发布版本号,草稿版本号为0 version = models.IntegerField(default=0) # 仅已发布的配置有且仅有一条为激活状态 is_active = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: constraints = [ # 保证每个企业同一时间只有一个激活的已发布配置 models.UniqueConstraint( fields=["company", "is_active"], condition=models.Q(is_active=True), name="unique_active_published_config_per_company" ) ]
2. 权限与查询过滤
通过DRF自定义权限类和查询集过滤,保证不同角色的可见范围符合需求:
自定义权限类
from rest_framework.permissions import BasePermission class DashboardConfigPermission(BasePermission): def has_permission(self, request, view): # 所有企业成员都有权限查询仪表盘配置 if request.method in ("GET", "HEAD", "OPTIONS"): return True # 新增/修改/发布操作仅企业管理员可操作 return request.user.is_company_admin # 你需要提前在User模型加这个权限标识字段
重写查询集过滤逻辑
在你的DashboardConfigViewSet中重写get_queryset方法,自动根据用户角色返回可见的配置:
def get_queryset(self): user = self.request.user user_company = user.company base_queryset = DashboardConfig.objects.filter(company=user_company) # 普通成员仅能看到企业当前激活的已发布配置 if not user.is_company_admin: return base_queryset.filter(status="published", is_active=True) # 管理员可以看到自己创建的草稿 + 企业当前激活的已发布配置 personal_drafts = base_queryset.filter(status="draft", created_by=user) published_config = base_queryset.filter(status="published", is_active=True) return personal_drafts | published_config
3. 核心业务接口实现
保存草稿接口
支持管理员随时保存未完成的配置,仅自己可见:
- 逻辑:校验用户为管理员,直接创建/更新
status="draft"的记录即可,不需要影响已发布配置 - 注意:草稿允许保存未校验完成的配置,不需要做严格的业务规则校验,降低使用门槛
发布草稿接口
管理员确认配置后触发发布,全企业成员可见:
from django.db import transaction from rest_framework.decorators import action from rest_framework.response import Response @action(methods=["POST"], detail=True) @transaction.atomic def publish(self, request, pk=None): draft = self.get_object() # 校验仅草稿创建者可发布 if draft.created_by != request.user or draft.status != "draft": return Response({"error": "仅草稿创建者可发布该配置"}, status=400) # 禁用之前的已发布激活配置 DashboardConfig.objects.filter( company=request.user.company, status="published", is_active=True ).update(is_active=False) # 生成新的已发布版本 latest_version = DashboardConfig.objects.filter( company=request.user.company, status="published" ).aggregate(models.Max("version"))["version__max"] or 0 published_config = DashboardConfig.objects.create( company=request.user.company, created_by=request.user, config_content=draft.config_content, status="published", version=latest_version + 1, is_active=True ) # 可选逻辑:发布后删除原草稿,或者保留供后续修改 # draft.delete() return Response({"status": "success", "published_version": published_config.version})
4. 并发场景兼容
如果存在多个管理员同时操作的场景,加数据库行级锁避免并发冲突:
在查询待发布草稿和旧的已发布配置时,加上select_for_update()即可:
# 发布接口查询草稿时替换为 draft = self.get_queryset().select_for_update().get(pk=pk) # 查询旧的已发布配置时替换为 DashboardConfig.objects.select_for_update().filter(...)
内容的提问来源于stack exchange,提问作者steelTissue
相关产品推荐
相关产品推荐

