DRF视图集之perform_update()方法
def perform_update(self, serializer):
"""
企业级用户信息更新处理(含安全审计日志)
核心功能:
1. 实现用户档案更新的完整生命周期管理
2. 生成符合SOX/GDPR等合规要求的审计记录
3. 确保操作可追溯性与数据变更完整性
安全特性:
- 变更前后数据对比
- 敏感操作全程记录
- 客户端环境信息捕获
"""
# 步骤1:获取更新前的用户档案对象
# 注意:使用get_object()而非直接访问数据库,确保权限验证已执行
# (权限验证由IsOwnerOrAdmin权限类在get_object阶段完成)
instance = self.get_object()
# 步骤2:捕获更新前的对象状态快照
# 使用__dict__获取原始字段值(排除ORM内部属性)
# 注意:对于外键/关联字段需单独处理,此处仅记录基础字段
old_data = {
k: v for k, v in instance.__dict__.items()
if not k.startswith('_') and k not in ['updated_at', 'created_at']
}
# 步骤3:智能检测数据变更
# 调用内部方法对比新旧数据,生成结构化变更描述
# 仅记录实际发生变更的字段,减少冗余日志
changes = self._detect_changes(old_data, serializer.validated_data)
# 步骤4:条件性创建安全审计事件
# 仅当存在实际变更时生成日志,避免空操作记录
if changes:
SecurityEvent.objects.create(
username=self.request.user.get_username(), # 记录操作用户名(支持自定义User模型)
event_type='USER_PROFILE_UPDATE', # 事件类型标准化,便于日志分析
details=f"更新{instance.nickname}个人信息: {changes}", # 人类可读的变更描述
ip_address=self._get_client_ip(), # 获取真实客户端IP(支持代理环境)
user_agent=self.request.META.get('HTTP_USER_AGENT', '')[:255] # 限制长度防止存储溢出
)
# 步骤5:执行数据更新
# 显式关联当前用户,防止越权操作(即使序列化器被篡改)
# 触发模型层save()方法,自动处理文件清理与时间戳更新
serializer.save(user=self.request.user)
# 扩展说明:
# 1. 审计日志设计遵循"不可篡改"原则,一旦创建无法修改
# 2. 客户端信息采集支持安全事件溯源与异常登录检测
# 3. 变更描述采用结构化文本,便于后续SIEM系统集成分析
# 4. 配合模型层的delete_old_avatar实现完整的文件生命周期管理