最近在使用django的时候遇到一个问题,模型的一个字段是DateTimeFiled类型,并且auto_now_add=True,在做业务的时候,需要通过这个事件来检索信息,问题就出现了:
DateTimeFiled类型字段在数据库存储格式是: 2019-12-05 17:00:48.997827
而业务中查询使用的是字符串:2019-12-05 17:00:48
这时候使用django的ORM查询如下:
Report.objects.filter(create='2019-12-05 17:00:48')
很明显结果一定是空!
于是怎么查成了一个问题,一般有2中办法:
1.不使用DateTimeFiled类型,使用CharFiled类型,写数据的时候自己获取格式化时间,然后插进去
2.懒得自己插入时间,查询的时候先获取DateTimeFiled字段然后格式化再查询,这里也有两种办法:
a.使用普通filter获取所有符合其他条件的数据,然后逐个格式化该字段,进行二次过滤
b.使用extra查询(重点)
extra是django orm提供的专门查询复杂语句的语法,比如现在这个需求,如果我们直接在mysql查询该信息,大致语句如下:
select * from report where DATE_FORMAT(`create`,'%Y-%m-%d %H:%M:%S')=DATE_FORMAT('2019-12-05 17:00:48','%Y-%m-%d %H:%M:%S')
ORM不支持date_format语法,此时就需要extra,等同的写法如下:
where_sql = ["DATE_FORMAT(`create`,'%%Y-%%m-%%d %%H:%%M:%%S')=DATE_FORMAT(%s,'%%Y-%%m-%%d %%H:%%M:%%S')"]
Report.objects.extra(where=where_sql,params=('2019-12-05 17:00:48',))
这里的where_sql就是查询的条件,写法就是mysql的语法,pamars是传递给where_sql的参数(%s),另外这里还需要注意一点,date_format()里面的格式化必须是2个%,我才大概是为了区分占位符%s吧。占位符%s如果有多个的话是按顺序取的,和平常的占位符一样。这里的create要带``,因为create在mysql中是关键字,不带会报错。