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

Django传递DateTime至TempusDominus时格式显示异常问题咨询

问题描述

编辑实体时,希望将DateTime传递至表单,但格式未按预期生效。空输入框中日期时间显示格式正确,但编辑已有字段时,显示格式为12/31/2024, 16:00。不过DateTime字符串已正确传递至表单,页面源码中也能看到正确格式2024-12-31 16:00,请问为何格式会被改变?

视图代码(Python)

def get_initial(self):
    initial = {
        'season': Season.objects.get(pk=self.request.session['selected_season_id']),
        'start': self.object.start.strftime('%Y-%m-%d') if self.object.allday else self.object.start.strftime('%Y-%m-%d %H:%M')
    }
    if self.object.end is not None:
        initial = {
            'end': self.object.end.strftime('%Y-%m-%d') if self.object.allday else self.object.end.strftime('%Y-%m-%d %H:%M')
        }
    return initial

表单JS配置(Tempus Dominus)

var picker = new tempusDominus.TempusDominus(document.getElementById(date_element_id), {
    //put your config here
    
    localization: {
        startOfTheWeek: 1,
        format: 'yyyy-MM-dd HH:mm',
        hourCycle: 'h24'
    },
    restrictions: {
        minDate: new Date(),
        maxDate: undefined,
        disabledDates: [],
        enabledDates: [],
        daysOfWeekDisabled: [],
        disabledTimeIntervals: [],
        disabledHours: [],
        enabledHours: [],

    }
});

picker.dates.formatInput = date => moment(date).format('yyyy-MM-DD HH:mm');

问题原因与解决方案

问题出在两个核心点:

  1. 视图代码的initial对象被覆盖
    处理end字段时,你直接重新赋值了initial字典,导致之前的start和season字段被完全覆盖丢失。需要改用update方法添加字段:
def get_initial(self):
    initial = {
        'season': Season.objects.get(pk=self.request.session['selected_season_id']),
        'start': self.object.start.strftime('%Y-%m-%d') if self.object.allday else self.object.start.strftime('%Y-%m-%d %H:%M')
    }
    if self.object.end is not None:
        # 使用update追加字段,而非重新创建字典
        initial.update({
            'end': self.object.end.strftime('%Y-%m-%d') if self.object.allday else self.object.end.strftime('%Y-%m-%d %H:%M')
        })
    return initial
  1. Tempus Dominus初始化时的解析与格式化逻辑冲突
    当输入框已有值时,组件会先将字符串解析为Date对象,再默认用浏览器格式渲染,而非你配置的自定义格式。需要在初始化后手动强制用自定义格式处理已有值:
var picker = new tempusDominus.TempusDominus(document.getElementById(date_element_id), {
    localization: {
        startOfTheWeek: 1,
        format: 'YYYY-MM-DD HH:mm',
        hourCycle: 'h24'
    },
    restrictions: {
        minDate: new Date(),
        maxDate: undefined,
        disabledDates: [],
        enabledDates: [],
        daysOfWeekDisabled: [],
        disabledTimeIntervals: [],
        disabledHours: [],
        enabledHours: [],
    }
});

// 统一用moment大写格式符,避免兼容性问题
picker.dates.formatInput = date => moment(date).format('YYYY-MM-DD HH:mm');

// 手动初始化已有值,强制按自定义格式渲染
const inputElement = document.getElementById(date_element_id);
if (inputElement.value) {
    const parsedDate = moment(inputElement.value, 'YYYY-MM-DD HH:mm');
    if (parsedDate.isValid()) {
        picker.dates.setValue(parsedDate.toDate());
    }
}

注意:moment的年份和日期格式符建议用大写YYYY和DD,小写格式符在部分场景下会出现解析异常。


内容的提问来源于stack exchange,提问作者cwhisperer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:57:35