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

如何在Django ORM中检查用户状态并按规则创建Timesheet

问题分析与解决方案

需求回顾

需在满足以下任意条件时为用户创建Timesheet,若用户存在Pending状态的休假记录,则禁止创建:

  • 存在状态为Cancelled和Approved的休假记录
  • 存在状态为Rejected和Cancelled的休假记录
  • 存在至少2条Cancelled状态的休假记录

现有代码的问题

  1. 未实现需求中的核心条件判断:当前代码仅查询了休假记录的存在性,但未验证三个创建条件,也未检查是否存在Pending状态
  2. 未将条件判断与Timesheet创建逻辑关联:无论是否满足条件,都会直接创建/更新Timesheet
  3. 存在冗余代码:比如User.objects.get(id=att.employee_id)可直接用att.employee替代,重复字段赋值可简化

修正后的代码实现

import calendar
from datetime import datetime
from django.db.models import Q

def submit_attendance(request, approval_status=None):
    if request.method == "POST":
        month = request.POST.get("month")
        year = request.POST.get("year")
        
        # 计算指定月份的起止日期
        year_int = int(year)
        month_int = int(month)
        first, last = calendar.monthrange(year_int, month_int)
        month_first_date = datetime.date(year_int, month_int, 1)
        month_last_day = datetime.date(year_int, month_int, last)

        # 获取当前用户指定月份内的考勤记录
        attendance_objects = Attendance.objects.filter(
            employee=request.user,
            date__month=month_int,
            date__year=year_int
        )

        # 获取当前用户指定月份内的所有休假记录状态
        leave_statuses = EmployeeLeaves.objects.filter(
            employee=request.user,
            from_date__gte=month_first_date,
            to_date__lte=month_last_day
        ).values_list('approval_status', flat=True)

        # 统计各休假状态的数量
        status_count = {}
        for status in leave_statuses:
            status_count[status] = status_count.get(status, 0) + 1

        # 判断是否满足Timesheet创建条件
        can_create = False
        if 'Pending' not in status_count:
            # 检查三个创建条件是否满足任意一个
            has_canceled = status_count.get('Cancelled', 0) >= 1
            condition1 = has_canceled and ('Approved' in status_count)
            condition2 = has_canceled and ('Rejected' in status_count)
            condition3 = status_count.get('Cancelled', 0) >= 2
            can_create = condition1 or condition2 or condition3

        # 仅当满足条件时,处理Timesheet的创建/更新
        if can_create:
            for att in attendance_objects:
                # 使用get_or_create简化创建/更新逻辑
                time_sheet_obj, created = Timesheet.objects.get_or_create(
                    employee=request.user,
                    date=att.date,
                    status=1,
                    defaults={
                        'workingday_holiday': att.workingday_holiday,
                        'in_time': att.in_time,
                        'out_time': att.out_time,
                        'shift': att.shift,
                        'working_hours': att.working_hours,
                        'remarks': att.remarks
                    }
                )
                # 如果是已存在的记录,更新字段
                if not created:
                    time_sheet_obj.workingday_holiday = att.workingday_holiday
                    time_sheet_obj.in_time = att.in_time
                    time_sheet_obj.out_time = att.out_time
                    time_sheet_obj.shift = att.shift
                    time_sheet_obj.working_hours = att.working_hours
                    time_sheet_obj.remarks = att.remarks
                    time_sheet_obj.save()
                
                # 更新考勤记录状态
                att.status = 0 if created else 1
                att.save()

关键优化点

  1. 核心条件判断:先统计休假状态的分布,严格按照需求验证创建条件,同时排除Pending状态的情况
  2. 简化创建逻辑:使用get_or_create替代try-except块,减少冗余代码,同时明确区分创建和更新场景
  3. 性能优化:批量获取休假状态而非多次查询,减少数据库交互次数
  4. 逻辑关联:仅当满足条件时才执行Timesheet的创建/更新操作,符合需求规则

内容的提问来源于stack exchange,提问作者Siva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 00:12:23