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

Angular Material时间选择器需求:仅返回hh:mm:ss格式时间适配Django后端

解决Angular Material时间选择器返回纯hh:mm:ss格式适配Django TimeField的问题

你遇到的核心问题是mdc-datetime-picker组件即使设置了date="false",返回的依然是Date对象,但Django的TimeField只接受纯时间字符串(如HH:mm:ss格式)。下面给你两种可行的解决方案:

方案1:在ng-change中手动转换时间格式

既然你已经绑定了ng-change="vm.saveChange()",可以直接在这个方法里把Date对象转成Django需要的纯时间字符串。假设你已经引入了moment.js(你之前提到用过),代码可以这样写:

// 控制器中的saveChange方法
vm.saveChange = function() {
  // 处理开门时间:将Date对象转为HH:mm:ss格式字符串
  if (opening.time instanceof Date) {
    opening.time = moment(opening.time).format('HH:mm:ss');
  }
  
  // 处理关门时间同理
  if (closing.time instanceof Date) {
    closing.time = moment(closing.time).format('HH:mm:ss');
  }
  
  // 后续发送请求到后端的逻辑...
};

注意:这里用HH(24小时制)是因为Django的TimeField默认解析24小时制时间字符串,即使你的组件显示的是12小时制(format="hh:mm a"),moment也会自动完成12小时到24小时的转换。

方案2:自定义ngModel指令自动转换(更优雅)

如果不想每次在ng-change里重复写转换逻辑,可以创建一个自定义Angular指令,自动在ngModel和组件之间做格式映射:

angular.module('你的应用模块名').directive('timeOnly', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      // 从组件(视图)到ngModel(模型):把Date对象转成HH:mm:ss字符串
      ngModel.$parsers.push(function(value) {
        if (value instanceof Date) {
          return moment(value).format('HH:mm:ss');
        }
        return value;
      });
      
      // 从ngModel(模型)到组件(视图):如果模型是字符串,转成Date对象让组件正确显示
      ngModel.$formatters.push(function(value) {
        if (typeof value === 'string') {
          return moment(value, 'HH:mm:ss').toDate();
        }
        return value;
      });
    }
  };
});

然后在你的时间选择器input上添加这个指令:

<md-input-container flex-gt-sm class="md-block">
  <label>Opening Time</label>
  <md-icon md-svg-src="/cityaplfreelisting/media/time.svg" class="mdicon"></md-icon>
  <input required mdc-datetime-picker date="false" time="true" type="text" 
         short-time="true" show-todays-date click-outside-to-close="true" 
         auto-ok="true" min-date="minDate" minute-steps="1" format="hh:mm a" 
         ng-change="vm.saveChange()" ng-model="opening.time" time-only>
</md-input-container>

<!-- 关门时间的input同样加上time-only指令 -->
<md-input-container flex-gt-sm class="md-block">
  <label>Closing Time</label>
  <md-icon md-svg-src="/cityaplfreelisting/media/time.svg" class="mdicon"></md-icon>
  <input required mdc-datetime-picker date="false" time="true" type="text" 
         short-time="true" show-todays-date click-outside-to-close="true" 
         auto-ok="true" min-date="minDate" minute-steps="1" format="hh:mm a" 
         ng-change="vm.saveChange()" ng-model="closing.time" time-only>
</md-input-container>

这样设置后,opening.time和closing.time会自动变成HH:mm:ss格式的字符串,直接符合Django TimeField的接收要求,无需额外处理。

额外注意点

  • 确保moment.js已经正确引入到你的项目中(如果还没引入,需要在页面中添加moment的脚本)。
  • 测试时可以在vm.saveChange()里打印opening.time的值,确认是纯时间字符串后再发送到后端。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:00:40