You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Никита Пешков

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 12:04:32