Django表单创建日期字段固化异常原因排查求助
Django表单创建日期字段固化异常原因排查求助
嘿,这个问题我之前也踩过坑,一眼就能找到问题根源!
你表单里create_date字段的widget.attrs['value']是直接在类定义阶段计算的:(datetime.today() + timedelta(hours=3)).strftime('%Y-%m-%d')——而Django的表单类是在gunicorn启动时加载一次,之后这个计算结果就被固化在内存里了,不会每次用户请求表单都重新计算!
对应到你的情况:
- 之前服务器在2024-10-07时启动(或重启)了gunicorn,所以这个value就固定成了10-07;
- 后来你重启gunicorn是10-09,代码重新执行了一次,value就变成了当天的日期。服务器时间正确但不影响这个固化结果,因为时间只在服务启动时读取了一次。
解决办法
你需要把日期计算逻辑移到表单的__init__方法里,让它每次创建表单实例时都重新计算:
from django import forms from datetime import datetime, timedelta class MyForm(forms.ModelForm): create_date = forms.DateField( input_formats=['%Y-%m-%d'], # 先去掉类定义里的value,留到__init__里动态设置 widget=forms.DateInput(attrs={'type': 'date', 'readonly': True}), label='Create date' ) product_cost = forms.IntegerField(label='Cost') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 每次初始化表单时,重新计算最新的日期 current_date = (datetime.today() + timedelta(hours=3)).strftime('%Y-%m-%d') self.fields['create_date'].widget.attrs['value'] = current_date
额外建议
如果这个create_date是用来记录表单提交的真实日期,更安全的做法是在模型层面处理:
在你的模型里把create_date字段设置为auto_now_add=True,这样每次保存对象时,后端会自动填充当前日期,完全不用在表单里处理,还能避免前端篡改(毕竟前端的readonly属性是可以被绕过的):
from django.db import models class YourModel(models.Model): create_date = models.DateField(auto_now_add=True) product_cost = models.IntegerField() # 其他字段...
这样表单里甚至可以不显示create_date字段,或者只做展示用,彻底规避这类问题~
备注:内容来源于stack exchange,提问作者Никита Пешков
相关产品推荐
相关产品推荐

