Django原生SQL中如何传递日期进行比较?
Django Raw SQL中替换硬编码日期的正确方法
问题核心
你当前的代码硬编码日期能正常运行,但替换为数据库当前日期函数或Python日期变量时出错,主要原因是日期函数使用不匹配或参数传递方式错误,同时原代码存在SQL注入风险,需要修正。
解决方案1:使用数据库原生的当前日期函数
不同数据库的当前日期函数不同,不要盲目使用TODAY(),以下是主流数据库的对应函数:
- MySQL/MariaDB:
CURDATE()或CURRENT_DATE() - PostgreSQL:
CURRENT_DATE - SQLite:
DATE('now') - SQL Server:
CAST(GETDATE() AS DATE)
同时必须用参数化方式传递taskidx,彻底避免SQL注入:
# 以MySQL为例,替换为CURDATE() overdue_phases = task.objects.raw(''' SELECT '1' as id, CASE WHEN research_due < CURDATE() AND research_status != 'done' THEN 1 ELSE 0 END as count FROM app_task WHERE taskid = %s ''', [taskidx])
解决方案2:传入Python日期变量
直接拼接Python日期字符串会导致格式适配问题,正确做法是将日期作为参数传入raw()方法的第二个参数列表,Django会自动处理数据库类型适配:
from datetime import date td = date.today() overdue_phases = task.objects.raw(''' SELECT '1' as id, CASE WHEN research_due < %s AND research_status != 'done' THEN 1 ELSE 0 END as count FROM app_task WHERE taskid = %s ''', [td, taskidx])
关键注意事项
- 禁止直接用字符串拼接SQL参数(如原代码中的
"+ taskidx +"),这会引发严重的SQL注入漏洞。 - 确保数据库日期函数与你使用的数据库类型匹配,否则会出现语法错误。
- 若
research_due是带时间戳的字段,可根据需求用DATE(research_due)提取日期部分再比较,避免时间干扰。
内容的提问来源于stack exchange,提问作者kikee1222
相关产品推荐
相关产品推荐

