You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django组织、部门与用户关联模型设计及实现问询

Hey there! Let's tackle your Organization-Department-User relationship model for Django. Based on your requirements—super users adding detailed departments, users belonging to multiple departments, and role-based edit permissions—I've put together a structured model setup that covers all bases:

Core Model Implementation

Here's the complete Django model code with comments explaining key choices:

from django.db import models
from django.contrib.auth.models import AbstractUser

class Organization(models.Model):
    name = models.CharField(max_length=30, unique=True)
    description = models.CharField(max_length=200, blank=True)
    
    def __str__(self):
        return self.name

class Department(models.Model):
    # Link each department to its parent organization
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name="departments")
    name = models.CharField(max_length=50)
    # Add required department details
    phone = models.CharField(max_length=20, blank=True)
    address = models.TextField(blank=True)
    email = models.EmailField(blank=True)
    # Link to the department's head (a user)
    head = models.ForeignKey('CustomUser', on_delete=models.SET_NULL, null=True, blank=True, related_name="managed_departments")
    
    class Meta:
        # Ensure no duplicate department names within the same organization
        unique_together = ('organization', 'name')
    
    def __str__(self):
        return f"{self.organization.name} - {self.name}"

class CustomUser(AbstractUser):
    # Link each user to their parent organization
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name="users")
    # Many-to-many relationship: users can belong to multiple departments
    departments = models.ManyToManyField(Department, related_name="members", blank=True)
    # Flag to identify organization-level super users
    is_org_superuser = models.BooleanField(default=False)
    
    def __str__(self):
        return self.username
Key Relationship Breakdown

Let's walk through how these models meet your requirements:

  • Organization ↔ Department: One-to-many link—each department lives under exactly one organization, and an org can have multiple departments. The unique_together constraint prevents duplicate department names in the same org.
  • Department ↔ User (Head): A one-to-many relationship lets a single user manage multiple departments. Using SET_NULL ensures deleting a head user won't accidentally delete the department itself.
  • User ↔ Department (Membership): Many-to-many setup allows users to be part of multiple departments, and departments to have multiple members. The related_name fields make it easy to query things like "all members of this department" or "all departments this user belongs to".
  • Organization Super Users: The is_org_superuser flag marks users with full control over their organization's departments and users.
Enforcing Edit Permissions

To make sure only department heads or org superusers can edit department/user details, you can add custom logic in your views. Here's a quick example:

from django.shortcuts import get_object_or_404
from django.http import HttpResponseForbidden

def edit_department(request, dept_id):
    department = get_object_or_404(Department, id=dept_id)
    
    # Check if the user has permission: org superuser OR department head
    if not (request.user.is_org_superuser or request.user == department.head):
        return HttpResponseForbidden("You don't have permission to edit this department.")
    
    # Proceed with your edit logic here...

For a more scalable approach, you can also create custom Django permissions (via the Meta class in your models) and assign them to the appropriate roles through the admin interface or programmatically.

内容的提问来源于stack exchange,提问作者niran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:52:21