【用戶管理與權限 - 篇四】后端權限定義:模型與 API 實現
- 前言
- 準備工作
- 第一部分:設計并創建 `Permission` 模型
- 第二部分:更新 `Role` 模型以關聯 `Permission`
- 第三部分:生成并應用數據庫遷移
- 第四部分:創建 Serializers
- 第五部分:創建 ViewSets
- 第六部分:注冊 API 路由
- 第七部分:通過數據遷移預置基礎權限數據
- 第八部分:后端 API 初步測試
- 總結
前言
在用戶管理與權限的前三篇文章中,我們已經成功搭建了用戶和角色的管理基礎,包括后端的模型、API 以及前端的用戶管理和角色管理界面。現在,是時候為我們的系統引入真正的“權限”概念了,這是實現細粒度訪問控制的核心。
本文將聚焦于后端權限的定義、模型設計以及相關的 API 實現,并確保我們有一些基礎的權限數據可供后續使用。我們將:
- 設計并創建一個
Permission
(權限) 模型,用于定義系統中各種可操作的權限點。 - 更新
Role
(角色) 模型,使其與Permission
模型建立多對多關聯,從而實現“角色擁有某些權限”的邏輯。 - 創建相應的 Serializer 和 ViewSet,提供獲取所有權限點列表以及更新角色所擁有權限的 API。
- 通過數據遷移預置一些基礎的權限數據,為后續前端的權限分配界面和后端的權限校驗做好準備。
什么是權限點 (Permission)?
權限點通常代表系統中一個具體的操作或對某個資源的訪問許可。例如:
view_project
(查看項目)add_project
(新建項目)manage_users
(管理用戶)
我們將這些權限點定義好后,就可以將它們分配給不同的角色,用戶通過繼承其角色的權限來獲得相應的操作能力。
準備工作
- Django 后端項目已就緒: 確保你的
test-platform/backend
項目結構完整,用戶和角色模型已創建。 - 數據庫遷移已同步。
- Postman 或其他 API 測試工具。
- 基礎模型 (
BaseModel
) 已定義 (假設包含name
,description
,create_time
,update_time
等通用字段)。
第一部分:設計并創建 Permission
模型
我們需要一個模型來存儲系統中的所有權限點。
-
在
api/models.py
中定義Permission
模型:
# test-platform/api/models.py import uuid from django.db import models from django.contrib.auth.models import User # ... (User, Role, UserProfile 等模型定義保持不變) ...class Permission(BaseModel):"""權限模型存儲系統中的原子權限點。'name' 和 'description' 字段從 BaseModel 繼承。"""# 權限編碼/標識符,應該是唯一的,用于程序內部判斷# 例如: 'project:view_list', 'project:create', 'user:manage'code = models.CharField(max_length=100, unique=True, verbose_name="權限編碼")# 權限分組,方便管理,例如 "項目管理", "用戶管理"group = models.CharField(max_length=50, null=True, blank=True, verbose_name="權限分組")class Meta:verbose_name = "權限"verbose_name_plural = "權限列表"ordering = ['group', 'name']def __str__(self):group_prefix = f"{self.group}: " if self.group else ""return f"{group_prefix}{self.name} ({self.code})"
代碼解釋:
code
: 權限的唯一編碼,這是程序進行權限判斷時主要依據的字段。建議使用一種有層級或模塊化的命名方式,如resource:action
(例如project:create
)。name
: 權限的易讀名稱,用于在界面上展示給管理員 (繼承自BaseModel
)。description
: 權限的詳細描述 (繼承自BaseModel
)。group
: 用于對權限進行邏輯分組,方便在權限分配界面展示。
第二部分:更新 Role
模型以關聯 Permission
現在,我們需要修改 Role
模型,使其能夠擁有多個權限。
-
在
api/models.py
中修改Role
模型:
# test-platform/api/models.py class Role(BaseModel):"""角色模型繼承自 BaseModel 以獲得 name, description, create_time, update_time 字段。"""permissions = models.ManyToManyField('Permission', # 關聯到 Permission 模型blank=True, verbose_name="角色權限",related_name="roles" # 從 Permission 可以通過 .roles 反向查詢擁有該權限的角色)class Meta:verbose_name = "角色"verbose_name_plural = "角色列表"ordering = ['name']def __str__(self):return self.name
關鍵變更:
permissions = models.ManyToManyField(Permission, ...)
: 在Role
模型上添加了一個多對多字段,直接關聯到Permission
模型。這意味著一個角色可以擁有多個權限,一個權限也可以被多個角色所擁有。
第三部分:生成并應用數據庫遷移
由于我們修改了 Role
模型并新增了 Permission
模型,需要進行數據庫遷移。
在終端中運行:
python manage.py makemigrations api
python manage.py migrate api
第四部分:創建 Serializers
我們需要為 Permission
模型創建一個 Serializer,并更新 RoleSerializer
以處理權限的關聯。
-
創建
PermissionSerializer
(api/serializers.py
):
# test-platform/api/serializers.py from typing import List from rest_framework import serializers from django.contrib.auth.models import User from .models import Project, Module, TestCase, TestPlan, TestRun, TestCaseRun, Permission, Role, UserProfile, User # 確保導入 Permission # ... (其他 Serializer) ...class PermissionSerializer(serializers.ModelSerializer):class Meta:model = Permission# BaseModel 包含 name, description, create_time, update_time# 確保你的 BaseModel 確實有這些字段,或者在這里顯式定義fields = ['id', 'name', 'code', 'description', 'group', 'create_time', 'update_time'