Django中models.DateTimeField如何存储不带秒数的日期时间值
Django 预约模型存储时间去除秒数解决方案
实现方案
要实现appointment_date字段存储精度仅到分钟,最稳妥的方式是在模型层重写save方法,所有写入数据库的该字段值都会自动清理秒和微秒,不受数据入口影响。
修改后的模型代码
from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ class Appointments(models.Model): options = ( ('waiting', '待确认'), ('confirmed', '已确认'), ('closed', '已结束'), ) duration_choices = ( ('15', '15分钟'), ('20', '20分钟'), ('30', '30分钟'), ('40', '40分钟'), ) date = models.DateTimeField(default=timezone.now) patient_first_name = models.CharField(max_length=250) patient_last_name = models.CharField(max_length=250) patient_email = models.EmailField(_('邮箱地址')) patient_phone = models.CharField(max_length=250) doctor = models.ForeignKey(Doctor, on_delete=models.PROTECT) room = models.ForeignKey(Room, on_delete=models.PROTECT, default=1) status = models.CharField(max_length=10, choices=options, default='waiting') message = models.TextField(null=True, blank=True) notes = models.TextField(null=True, blank=True) appointment_date = models.DateTimeField(null=True, blank=True) duration = models.CharField(max_length=10, choices=duration_choices, default='15') def save(self, *args, **kwargs): if self.appointment_date: # 清除秒和微秒,仅保留到分钟 self.appointment_date = self.appointment_date.replace(second=0, microsecond=0) super().save(*args, **kwargs) class Meta: ordering = ('-date', ) unique_together = ('appointment_date', 'room', )
注意事项
- 原代码中
duration字段名和选项元组名重复,已将选项元组重命名为duration_choices避免冲突 - 如果你开启了Django时区功能,
replace方法会自动保留时区信息,不会出现时间偏移问题 - 已存入数据库的历史数据需要批量清理秒数,避免旧数据触发唯一约束冲突,可在Django Shell中执行以下脚本处理:
from yourapp.models import Appointments for item in Appointments.objects.all(): if item.appointment_date: item.appointment_date = item.appointment_date.replace(second=0, microsecond=0) item.save(update_fields=['appointment_date'])
- 若项目使用DRF序列化器或Django表单提交数据,也可以在验证阶段提前清理秒数,和模型层逻辑做双重保障。
内容的提问来源于stack exchange,提问作者ActaDennis
相关产品推荐
相关产品推荐

