
有这样一个 Model:
class InfoModel: title = models.CharField('标题', max_length=50) create_date = models.DateField('创建日期', auto_now_add=True) expiration = models.IntegerField('有效期 x 天', default=0) 要查询当前时间点未过期的的数据.
1 chenstack Jan 17, 2020 为什么不存一个到期日期的字段呢 |
3 chenstack Jan 17, 2020 Django 的 F 表达式可以在查询或更新时对字段做加、减、乘、除、取模和幂运算等算术操作,但你的字段是日期类型的,没有这样做过,我搜到了类似这样的回答 https://stackoverflow.com/questions/38703016/what-is-the-replacement-for-datemodifiernode-in-new-versions-of-django 晚点我自己试一下 |
4 liulei281 OP @chenstack 这些我昨天查了很多, 没找到合适的办法. 我目前想到的解决办法: InfoModel.objects.annotate(delta=ExpressionWrapper((Value(now().date(), DateField()) - F('display_date')) / (24 * 60 * 60 * 1000 * 1000), output_field=IntegerField())).filter(expiration__gte=delta) 看着很恶心... |
5 liulei281 OP @chenstack 如果能调用 Mysql 的 CURDATE, TODAYS, INTERVAL 之类的方法就会简单很多, 但是貌似 django 不支持 |
6 0dJ6Tu8Za734L89T Jan 17, 2020 @liulei281 谨慎使用这些函数,在 where 上不正确使用会走不了索引的吧 |
7 SjwNo1 Jan 17, 2020 表数据量不大建议刷表 expiration 改成到期时间 后续 query |
8 Vegetable Jan 17, 2020 不是,不说 orm,你这个查询我用 sql 也不会写,写出来也不知道能不能走索引,也不知道会不会每行都计算一个 now |
9 ytymf Jan 17, 2020 换个思路吧,不追求在数据库一次性返回好,把判断过期放在数据库外做,效率应该不会差特别多, 内存得注意。不知道数据库表有多大呢? 伪代码,胡写的。 resultList= [] for each in InfoModel.objects.all(): if datetime.now()-each.expiration < each.create_date: resultList.append() |
10 ytymf Jan 17, 2020 resultList.append(each),写错了 |
11 lonelinsky Jan 17, 2020 1. data migration 2. raw SQL :-) |
12 izoabr Jan 17, 2020 你干脆加一个 model,两个字段,第一个字段关联 InfoModel,第二个字段到期时间。 第一个字段做主键,第二个字段自动生成,可以直接写到 class 里。 然后 Super 一下 InfoModel 的 create 方法,顺路去创建一个你的新 model 记录。 |
13 daya Jan 17, 2020 计算出当前日期跟创建日期相差多少天,然后跟有效期存的天数比较大小不行吗 |
14 bogun Jan 17, 2020 存成日期格式,建表加上索引。可以参考 django session 的过期机制实现 |
15 Jammar Jan 17, 2020 写个脚本,计算一下剩余日期重新建议一个表,这个就删了吧 |
16 oaix Jan 17, 2020 在 sql 层,可以使用 generated column,有个明显的优势就是可以在它上面建索引。 |
17 wd Jan 17, 2020 via iPhone 你加一个自定义的计算字段,然后根据那两个字段产生?另外,如果已经知道原来设计不合理就想想怎么改吧,继续往屎堆拉屎只能让他变得更难清理。 |