Django数据库重复数据校验问题:多日期检测失效求助
Django重复数据检测问题排查与解决
问题场景
在Django中实现基于姓名(name)和出行日期(date_travel)的重复数据校验:当添加姓名为Lebron James的记录时,通过flatpickr选择多个日期(如24-08-2023、25-08-2023),其中24-08-2023已存在于该姓名的记录中,预期返回JsonResponse提示"Duplicate date travel",但当前代码始终返回成功状态,无法检测到重复数据。
现有代码
视图函数
@csrf_exempt def item_add(request): employeename = request.POST.get('EmployeeName') travel_date = request.POST.get('DateTravel') # Split the date string into individual dates individual_dates = travel_date.split(',') for date in individual_dates: cleaned_date = date.strip() query = """ SELECT date_travel FROM tev_incoming WHERE name = %s AND date_travel LIKE %s; """ with connection.cursor() as cursor: cursor.execute(query, [employeename, cleaned_date]) results = cursor.fetchall() if results: return JsonResponse({'data': 'error', 'Duplcate date travel':results}) else: return JsonResponse({'data': 'success', 'message': "Unique travel and name"})
HTML输入框
<input type="text" class="form-control" name="DateTravel" placeholder="DD-MM-YYYY" id="dateField"/>
flatpickr脚本
$('#dateField').flatpickr({ mode: 'multiple', allowInput: true, dateFormat: 'd-m-Y', locale: { firstDayOfWeek: 1 // start week on Monday }, });
问题排查与修复方案
1. 循环逻辑错误(核心问题)
当前代码在循环的第一次迭代就直接返回结果:如果第一个日期不存在,直接返回成功,不会继续检查后续日期。这就导致如果重复日期不是第一个被遍历的,永远不会被检测到。
修复方法:将return JsonResponse({'data': 'success'})移到循环结束之后,循环内只负责检测重复,发现重复立即返回错误;所有日期检查通过后,再返回成功。
2. 日期格式不匹配
数据库中的date_travel字段如果是Date类型,存储格式通常是YYYY-MM-DD,但前端传的是DD-MM-YYYY,直接用字符串对比(或LIKE)会完全不匹配,导致查询不到已存在的记录。
修复方法:将前端传入的日期字符串转换为Django可识别的日期对象,再与数据库字段对比:
from datetime import datetime cleaned_date = date.strip() # 转换前端DD-MM-YYYY格式为日期对象 try: converted_date = datetime.strptime(cleaned_date, '%d-%m-%Y').date() except ValueError: return JsonResponse({'data': 'error', 'message': 'Invalid date format'})
3. 原生SQL查询的潜在问题
使用原生SQL的LIKE进行日期匹配没必要,且容易出错;建议改用Django ORM,更安全、简洁,还能自动处理日期类型转换。
假设你的模型类是TevIncoming,对应表tev_incoming:
from .models import TevIncoming # 替换原生SQL查询为ORM if TevIncoming.objects.filter(name=employeename, date_travel=converted_date).exists(): return JsonResponse({'data': 'error', 'message': f'Duplicate date travel: {cleaned_date}'})
修复后的完整视图函数
@csrf_exempt def item_add(request): employeename = request.POST.get('EmployeeName') travel_date = request.POST.get('DateTravel') if not employeename or not travel_date: return JsonResponse({'data': 'error', 'message': 'Missing required fields'}) individual_dates = travel_date.split(',') from datetime import datetime from .models import TevIncoming for date_str in individual_dates: cleaned_date_str = date_str.strip() try: converted_date = datetime.strptime(cleaned_date_str, '%d-%m-%Y').date() except ValueError: return JsonResponse({'data': 'error', 'message': f'Invalid date format: {cleaned_date_str}'}) # 检查重复 if TevIncoming.objects.filter(name=employeename, date_travel=converted_date).exists(): return JsonResponse({'data': 'error', 'message': f'Duplicate date travel: {cleaned_date_str}'}) # 所有日期检查通过,这里可以添加批量创建记录的逻辑 return JsonResponse({'data': 'success', 'message': "All dates are unique for this employee"})
内容的提问来源于stack exchange,提问作者BootCamp
相关产品推荐
相关产品推荐

