Django考勤管理系统如何更新指定日期已存在的考勤表数据
解决方案
你要实现的「同日期同员工考勤不存在则创建、存在则更新」的需求,Django提供了内置方法update_or_create可以直接满足,无需自行编写判断逻辑,同步可调整以下内容避免重复数据问题:
一、模型层优化(建议优先调整)
原有attendance表没有做重复校验,容易从数据库层面产生冗余数据,可增加联合唯一约束保证同员工同日期仅存在一条考勤记录:
from django.db import models class staff(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=250, null=True) role = models.CharField(max_length=250, null=True) salary = models.CharField(max_length=250, null=True) address = models.CharField(max_length=250, null=True) number = models.CharField(max_length=250, null=True) date = models.DateField() class attendance(models.Model): id = models.AutoField(primary_key=True) staff_id = models.CharField(max_length=250, null=True) attendance = models.CharField(max_length=250, null=True) date = models.DateField() class Meta: # 联合唯一约束,从数据库层面避免同员工同日期多条考勤记录 unique_together = ('staff_id', 'date')
如果后续有性能优化需求,建议将staff_id改为外键关联staff模型,数据一致性更高
二、视图层代码修改
将原有直接新建实例保存的逻辑,替换为update_or_create方法即可:
def index(request): staffs = staff.objects.all() staff_ids = staff.objects.values_list('id', flat=True) attendances = attendance.objects.all() amounts = amount.objects.all() today = datetime.date.today() if request.method == "POST" : for staff_id in staff_ids: stf_key = 'staff_id' + str(staff_id) atd_key = 'attendance' + str(staff_id) current_staff_id = request.POST.get(stf_key, None) attendance_status = request.POST.get(atd_key, None) # 核心逻辑:同员工同日期则更新考勤状态,否则新建记录 attendance.objects.update_or_create( # 查询匹配条件 staff_id=current_staff_id, date=today, # 需要更新/写入的字段 defaults={'attendance': attendance_status} ) return HttpResponseRedirect("/index") return render(request, "salary/index.html", {'staff': staffs, 'attendance': attendances, 'amount': amounts, 'date': today})
逻辑说明
update_or_create的执行规则:
- 先根据
defaults之外的参数作为查询条件,匹配数据库中已有的记录 - 匹配到记录则更新
defaults内的字段值,执行更新操作 - 未匹配到记录则合并查询条件和
defaults字段,执行新增操作
配合模型层的联合唯一约束,可完全避免重复考勤记录生成。
内容的提问来源于stack exchange,提问作者Path Parakh
相关产品推荐
相关产品推荐

