如何在Django中创建仅可创建企业的RootUser?
实现RootUser的方案(无需单独开发应用)
你的需求可以通过扩展现有CustomUser模型+新增企业关联模型+细粒度权限控制实现,不需要单独开发应用,以下是具体思路:
1. 新增企业模型(Enterprise)
首先需要一个Enterprise模型来建立RootUser与企业的归属关系,以及企业和下属用户的关联:
from django.db import models from .models import CustomUser class Enterprise(models.Model): name = models.CharField(max_length=255, unique=True) created_by = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='owned_enterprises') created_at = models.DateTimeField(auto_now_add=True) class Meta: permissions = [ ("can_create_enterprise", "Can create enterprise"), ] def __str__(self): return self.name
这里同时定义了can_create_enterprise自定义权限,用于限制只有RootUser能创建企业。
2. 扩展CustomUser模型
修改现有CustomUser,添加RootUser类型和企业关联字段:
class CustomUser(AbstractUser): USER_TYPE_CHOICES = ( (0, "Root User"), # 新增Root用户类型 (1, "Super Admin"), (2, "Staff"), (3, "Users"), ) user_id = models.IntegerField(unique=True) # IntegerField无需max_length,已移除 user_type = models.IntegerField(choices=USER_TYPE_CHOICES, default=3) phone_number = models.CharField(max_length=500) nid_number = models.CharField(max_length=100, blank=True) city_name = models.CharField(max_length=100, blank=True) zip_code = models.CharField(max_length=10, blank=True) nid_image = models.ImageField(upload_to='nid_images', blank=True) address = models.TextField(blank=True) # 关联所属企业,RootUser此字段为null enterprise = models.ForeignKey(Enterprise, on_delete=models.SET_NULL, null=True, blank=True, related_name='enterprise_users') last_active = models.DateTimeField(default=timezone.now) profile_picture = models.ImageField(upload_to='profile_pictures', blank=False) # 保留原有is_online和save方法...
- RootUser的
enterprise字段留空,因为它不属于任何企业,而是拥有企业; - 普通用户/企业管理员必须关联到某一企业,后续通过信号或验证确保这一点。
3. 权限与数据隔离控制
3.1 视图层面过滤数据
在所有涉及数据访问的视图中,根据用户类型过滤查询集:
from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import CreateView, ListView from django.http import HttpResponseForbidden from .models import Enterprise, CustomUser # RootUser专属:创建企业视图 class EnterpriseCreateView(LoginRequiredMixin, CreateView): model = Enterprise fields = ['name'] def form_valid(self, form): if self.request.user.user_type != 0: return HttpResponseForbidden("仅Root User可创建企业") form.instance.created_by = self.request.user return super().form_valid(form) # 企业用户查看本企业用户列表 class CustomUserListView(LoginRequiredMixin, ListView): model = CustomUser def get_queryset(self): current_user = self.request.user # RootUser禁止查看任何用户数据 if current_user.user_type == 0: return CustomUser.objects.none() # 普通用户仅能查看所属企业的用户 return CustomUser.objects.filter(enterprise=current_user.enterprise)
3.2 模型层面确保数据合法性
用信号防止普通用户未关联企业:
from django.db.models.signals import pre_save from django.dispatch import receiver @receiver(pre_save, sender=CustomUser) def validate_user_enterprise(sender, instance, **kwargs): # 非Root用户必须关联企业 if instance.user_type != 0 and not instance.enterprise: raise ValueError("非Root用户必须隶属于某一企业")
4. 创建RootUser实例
通过Django Shell创建RootUser并分配权限:
python manage.py shell
执行以下代码:
from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission CustomUser = get_user_model() # 创建RootUser root_user = CustomUser.objects.create_user( username="root", password="your_secure_password", user_type=0, phone_number="1234567890", profile_picture="path/to/default_profile.jpg" # 按模型要求提供图片路径 ) # 分配创建企业的权限 create_perm = Permission.objects.get(codename="can_create_enterprise") root_user.user_permissions.add(create_perm) root_user.save()
方案优势
- 无需拆分应用,代码集中维护;
- 严格的数据隔离:RootUser仅能创建企业,无法访问任何企业的用户或业务数据;
- 权限粒度可控:通过自定义权限而非默认superuser,避免权限溢出;
- 扩展灵活:后续可基于企业模型添加更多业务逻辑(如企业配置、数据隔离规则等)。
内容的提问来源于stack exchange,提问作者user2972318
相关产品推荐
相关产品推荐

