You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF优化Attendance模型Create/Update实现:解决更新返回字段为空问题

解决Attendance序列化器的create_or_update优化及返回值问题

问题背景

Attendance模型的user外键与date字段设置了联合唯一约束,当前用if-else实现的创建或更新逻辑冗余不够优雅,而且执行update操作后返回的对象所有字段为空。

问题原因

  1. Attendance.objects.update()方法返回的是受影响的行数,并非模型实例,这就是返回空对象的核心原因;
  2. 多层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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:55:19