DRF优化Attendance模型Create/Update实现:解决更新返回字段为空问题
解决Attendance序列化器的create_or_update优化及返回值问题
问题背景
Attendance模型的user外键与date字段设置了联合唯一约束,当前用if-else实现的创建或更新逻辑冗余不够优雅,而且执行update操作后返回的对象所有字段为空。
问题原因
Attendance.objects.update()方法返回的是受影响的行数,并非模型实例,这就是返回空对象的核心原因;- 多层if-else写法重复代码多,逻辑冗余,不符合简洁性原则。
优化后的序列化器代码
from rest_framework import serializers from django.utils import timezone from .models import Attendance class AttendanceSerializer(serializers.ModelSerializer): date = serializers.HiddenField(default=timezone.now) leave_reason = serializers.CharField(required=False, default="") class Meta: model = Attendance fields = ['user', 'presence', 'leave_reason', 'date'] extra_kwargs = { 'user': {'required': True}, 'presence': {'required': True}, 'leave_reason': {'required': False}, } # 启用联合唯一验证,提前拦截重复提交 validators = [ serializers.UniqueTogetherValidator( queryset=Attendance.objects.all(), fields=['user', 'date'], message="该用户今日已提交过考勤记录" ) ] def create(self, validated_data): # 用Django内置的update_or_create直接实现创建/更新逻辑 instance, _ = Attendance.objects.update_or_create( # 联合唯一的查询条件 user=validated_data['user'], date=validated_data['date'], # 需要更新的字段集合 defaults={ 'presence': validated_data['presence'], 'leave_reason': validated_data['leave_reason'] } ) return instance
优化说明
- 修复返回值问题:
update_or_create返回(实例对象, 是否新创建)的元组,直接返回实例即可确保返回完整的模型对象; - 简化逻辑:用一行代码替代多层if-else,消除重复代码,符合Django最佳实践;
- 提前验证:启用
UniqueTogetherValidator在序列化层提前校验,避免触发数据库层面的约束错误,提升接口友好性; - 避免变量覆盖:原代码中存在查询实例变量名覆盖
user的问题,优化后彻底避免这类逻辑错误。
内容的提问来源于stack exchange,提问作者rediet yosef
相关产品推荐
相关产品推荐

