Django ViewSet重写:Inventory变更自动更新InventoryHistory的实现疑问
解决方案
1. 示例模型结构
假设你的模型定义如下:
from django.db import models class Inventory(models.Model): product = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.IntegerField() last_updated = models.DateTimeField(auto_now=True) class InventoryHistory(models.Model): inventory = models.ForeignKey(Inventory, on_delete=models.CASCADE, related_name='history') old_quantity = models.IntegerField() new_quantity = models.IntegerField() changed_at = models.DateTimeField(auto_now_add=True) changed_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
2. 定义序列化器
from rest_framework import serializers from .models import Inventory, InventoryHistory class InventorySerializer(serializers.ModelSerializer): class Meta: model = Inventory fields = ['id', 'product', 'quantity', 'last_updated'] class InventoryHistorySerializer(serializers.ModelSerializer): class Meta: model = InventoryHistory fields = ['id', 'old_quantity', 'new_quantity', 'changed_at', 'changed_by']
3. 重写ViewSet实现自动记录历史
ViewSet仅用InventorySerializer处理前端请求,历史记录逻辑在内部自动完成:
from rest_framework import viewsets from .models import Inventory, InventoryHistory from .serializers import InventorySerializer from rest_framework.response import Response from rest_framework import status class InventoryViewSet(viewsets.ModelViewSet): queryset = Inventory.objects.all() serializer_class = InventorySerializer def create(self, request, *args, **kwargs): # 处理库存创建 serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) inventory = serializer.save() # 创建初始历史记录(旧数量为0) InventoryHistory.objects.create( inventory=inventory, old_quantity=0, new_quantity=inventory.quantity, changed_by=request.user if request.user.is_authenticated else None ) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() # 保存更新前的库存数量 old_quantity = instance.quantity # 执行库存更新 serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) inventory = serializer.save() # 仅当数量发生变化时创建历史记录 if old_quantity != inventory.quantity: InventoryHistory.objects.create( inventory=inventory, old_quantity=old_quantity, new_quantity=inventory.quantity, changed_by=request.user if request.user.is_authenticated else None ) return Response(serializer.data)
核心要点
- 无需在ViewSet中暴露
InventoryHistorySerializer,历史记录完全由后端自动生成,不接收前端提交的历史数据。 - 更新操作中增加数量对比逻辑,避免生成无意义的重复历史记录。
- 操作人字段直接通过
request.user获取,兼容未登录场景(设为None)。 - 如果需要支持批量更新、删除等操作,可在对应的ViewSet方法中添加类似的历史记录创建逻辑。
内容的提问来源于stack exchange,提问作者M Abbas Baloch
相关产品推荐
相关产品推荐

