DRF中仅更新模型两个字段时其他字段为空的问题
问题原因与解决方案
核心问题
你创建了一个新的Card实例requestd2 = card.models.Card(card_number=requestd),这个实例只有card_number字段有值,其余字段都是默认空值。当你用这个新实例执行partial=True的更新时,DRF会把这个新实例的空字段也保存到数据库,覆盖原有数据,导致其他字段变空。
正确的做法是从数据库获取已存在的Card实例,而非新建实例。
修正后的代码
from rest_framework.decorators import api_view from rest_framework import status from rest_framework.response import Response from card.models import Card from .serializers import CardModelSerializer @api_view(['GET', 'PUT', 'DELETE']) def snippet_detail(request, format=None): try: # 从请求数据中获取卡号(用request.data兼容PUT/POST请求) card_number = request.data.get('card_number') if not card_number: return Response('卡号不能为空', status=status.HTTP_400_BAD_REQUEST) # 从数据库获取已存在的Card实例 card_instance = Card.objects.get(card_number=card_number) current_credit = card_instance.initial_credit request_credit = int(request.data.get('initial_credit', 0)) except Card.DoesNotExist: return Response('卡号不存在', status=status.HTTP_404_NOT_FOUND) except ValueError: return Response('输入的金额格式错误', status=status.HTTP_400_BAD_REQUEST) if request.method == 'PUT': # 使用数据库中已存在的实例执行部分更新 serializer = CardModelSerializer(card_instance, data=request.data, partial=True) if serializer.is_valid(): comment = 'اعتبار کافی نمی باشد .' comment2 = 'مقدار وارد شده صحیح نمی باشد' if request_credit <= 0: return Response(comment2, status=status.HTTP_400_BAD_REQUEST) new_credit = current_credit - request_credit if new_credit >= 0: # 更新余额字段 serializer.validated_data['initial_credit'] = new_credit serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) else: return Response(comment, status=status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
关键优化点
- 实例获取修正:用
Card.objects.get(card_number=card_number)获取数据库中已有的记录,避免用新实例覆盖数据 - 请求数据兼容:用
request.data替代request.POST,适配DRF中PUT请求的数据处理逻辑 - 异常处理完善:新增金额格式错误的捕获逻辑,避免非数字输入导致报错
- 逻辑顺序调整:先校验金额合法性,再计算余额,代码逻辑更清晰
- 字段更新方式:通过
serializer.validated_data直接修改余额,确保更新后的数据正确
内容的提问来源于stack exchange,提问作者amin tavakoli
相关产品推荐
相关产品推荐

