Django中日期处理注意事项与自定义时间格式转换详解


Posted in Python onAugust 06, 2018

前言

我们在用Django创建models时,常常会涉及时间日期字段的处理,Django里日期相关Field有DateTimeField、DateField和TimeField三种类型,看似简单,但其中有一些容易出错的地方需要注意;另外,如果不习惯Django的默认时间格式,也可以自定义的修改。

DateTimeField、DateField和TimeField,其值分别对应着Python里的datetime.datetime、datetime.date和datetime.time三个实例,这三个Field里都有两个参数:auto_now和auto_now_add,默认值均为False。

auto_now参数说明:

每次保存对象时自动将字段值设置为当前时间,能够在保存该字段时,将其值设置为当前时间,并且每次修改model,都会自动更新。因此这个参数在需要存储“最后修改时间”的场景下,十分方便,常用类似“last-modified”或者"update_time"字段。

需要注意的是,该字段不能被手动修改覆盖;当设置为true时,只有每次调用Model.save()时,才会强制更新为当前时间点;当用其他方式更新其他字段时并不会更新:比如用QuerySet.update()方法,即使为该字段指定一个自定义的值,该字段也不会有所更改。比较直观的表现形式是,如果使用django自带的admin管理器,那么该字段在admin中是只读的,并且无法进行修改。

示例代码如下:

class Datacenter(models.Model):
 id = models.UUIDField('机房ID', default=uuid.uuid4, primary_key=True)
 zone = models.ForeignKey(Zone, verbose_name='所在区域', on_delete=models.PROTECT)
 dc_name = models.CharField('机房', max_length=128, unique=True)
 networks = models.CharField('IP地址段', max_length=128, blank=True, unique=True)
 update_time = models.DateTimeField('更新时间', auto_now=True)

 def __str__(self):
 return self.dc_name

 class Meta:
 verbose_name = '机房配置'
 verbose_name_plural = '机房配置'

Datacenter的ModelAdmin代码:

class DatacenterAdmin(admin.ModelAdmin):
 list_display = ['id', 'dc_name', 'zone', 'networks', 'update_time']
 search_fields = ['dc_name', 'zone', 'networks']
 list_filter = ['dc_name', 'zone']
 ordering = ['networks', 'zone']
admin.site.register(models.Datacenter, DatacenterAdmin)

Admin界面效果图:

Django中日期处理注意事项与自定义时间格式转换详解

点击编辑页面,会发现找不到‘更新时间'的编辑处,因为此字段是只读,且不允许手动修改,效果图如下:

Django中日期处理注意事项与自定义时间格式转换详解

当页面“save”之后,再观察现在的‘更新时间'发现时间已经被修改:

Django中日期处理注意事项与自定义时间格式转换详解

auto_now_add参数说明:

设置为True时,会在model对象第一次被创建时,将字段的值设置为创建时的时间,以后修改对象时,字段的值不会再更新。该属性通常被用在存储“创建时间”的场景下。与auto_now类似,auto_now_add也具有强制性,一旦被设置为True,就无法在程序中手动为字段赋值,在admin中字段也会成为只读的。

继续沿用刚才的代码示例,'update_time'的'auto_now'改完'auto_now_add',其他代码不变:

class Datacenter(models.Model):
 id = models.UUIDField('机房ID', default=uuid.uuid4, primary_key=True)
 zone = models.ForeignKey(Zone, verbose_name='所在区域', on_delete=models.PROTECT)
 dc_name = models.CharField('机房', max_length=128, unique=True)
 networks = models.CharField('IP地址段', max_length=128, blank=True, unique=True)
 update_time = models.DateTimeField('更新时间', auto_now_add=True)

编辑更新北京联通机房的IP地址段之后保存:

Django中日期处理注意事项与自定义时间格式转换详解

更改之后‘更新时间'并未发生改变(见下图),因为‘auto_now_add'在对象创建完成后即不再更新:

Django中日期处理注意事项与自定义时间格式转换详解

如何实现可编辑

auto_now和auto_now_add被设置为True后,这样做会导致字段成为editable=False和blank=True的状态。editable=False将导致字段不会被呈现在admin中,blank=Ture表示允许在表单中不输入值。此时,如果在admin的fields或fieldset中强行加入该日期时间字段,那么程序会报错,admin无法打开;如果在admin中修改对象时,想要看到日期和时间,可以将日期时间字段添加到admin类的readonly_fields中:

readonly_fields = ('save_date', 'mod_date',)

那么问题来了。实际场景中,往往既希望在对象的创建时间默认被设置为当前值,又希望能在日后修改它。怎么实现这种需求呢?

django中所有的model字段都拥有一个default参数,用来给字段设置默认值。可以用default=timezone.now来替换auto_now=True或auto_now_add=True。timezone.now对应着django.utils.timezone.now(),代码示例:

from django.utils import timezone

class Datacenter(models.Model):
 id = models.UUIDField('机房ID', default=uuid.uuid4, primary_key=True)
 zone = models.ForeignKey(Zone, verbose_name='所在区域', on_delete=models.PROTECT)
 dc_name = models.CharField('机房', max_length=128, unique=True)
 networks = models.CharField('IP地址段', max_length=128, blank=True, unique=True)
 update_time = models.DateTimeField('更新时间', default=timezone.now())

 def __str__(self):
  return self.dc_name

 class Meta:
  verbose_name = '机房配置'
  verbose_name_plural = '机房配置'

这里'update_time'字段默认值改为timezone.now()后,再次编辑已经能看到相应‘更新时间'字段,并且可修改:

Django中日期处理注意事项与自定义时间格式转换详解

我们把时间天数加1天后,保存退出再观察‘更新时间'已经变为自定义时间:

Django中日期处理注意事项与自定义时间格式转换详解

自定义日期格式:
刚创建的Django应用,可能你看到的日期显示格式跟下图类似(跟LANGUAGE_CODE和TIME_ZONE有关):

![可能的默认日期格式](http://i2.51cto.com/images/blog/201803/23/164dc709843a56536c09c9142775a553.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

如果不习惯这种格式,自己定义显示格式的配置如下,更改Django的setting.py文件:

USE_L10N = False
DATE_FORMAT = 'Y-m-d'
DATETIME_FORMAT = 'Y-m-d H:i:s'

注意事项:如果USE_L10N设置为了True,那么语言环境规定的格式具有更高的优先级并将被应用,即DATE_FORMAT不生效。

这里可用的格式化字符串的其他写法参见Django官方文档:

<https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#date>;

Django中日期处理注意事项与自定义时间格式转换详解

Django中日期处理注意事项与自定义时间格式转换详解

另外在Django页面渲染的时候,html页面从数据库中读出DateTimeField字段时,显示的时间格式和数据库中存放的格式不一致,另外一个解决办法:可以在页面格式化时间,添加{{ Datacenter.updatetime|date:"Y-m-d H:i:s" }}类似的过滤器。之后刷新页面,即可正常显示。

相关文档:

https://docs.djangoproject.com/en/2.0/ref/settings/

https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#std:templatefilter-date

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python实现 多进程导入CSV数据到 MySQL
Feb 26 Python
Python OpenCV处理图像之滤镜和图像运算
Jul 10 Python
Python实现多线程的两种方式分析
Aug 29 Python
对Python使用mfcc的两种方式详解
Jan 09 Python
Python设计模式之原型模式实例详解
Jan 18 Python
TensorFlow卷积神经网络之使用训练好的模型识别猫狗图片
Mar 14 Python
numpy.random模块用法总结
May 27 Python
在python中做正态性检验示例
Dec 09 Python
Python devel安装失败问题解决方案
Jun 09 Python
Python使用itcaht库实现微信自动收发消息功能
Jul 13 Python
Python中实现一行拆多行和多行并一行的示例代码
Sep 06 Python
python中绕过反爬虫的方法总结
Nov 25 Python
python 地图经纬度转换、纠偏的实例代码
Aug 06 #Python
Anaconda下配置python+opencv+contribx的实例讲解
Aug 06 #Python
Django添加sitemap的方法示例
Aug 06 #Python
python中scikit-learn机器代码实例
Aug 05 #Python
解决使用pycharm提交代码时冲突之后文件丢失找回的方法
Aug 05 #Python
Python字符串、整数、和浮点型数相互转换实例
Aug 04 #Python
python与caffe改变通道顺序的方法
Aug 04 #Python
You might like
DOTA2 6.87版本后新眼位详解攻略
2020/04/20 DOTA
php模板中出现空行解决方法
2011/03/08 PHP
php获取网页中图片、DIV内容的简单方法
2014/06/19 PHP
php分割合并两个字符串的函数实例
2015/06/19 PHP
WordPress主题制作之模板文件的引入方法
2015/12/28 PHP
PHP 的比较运算与逻辑运算详解
2016/05/12 PHP
laravel实现查询最后执行的一条sql语句的方法
2019/10/09 PHP
用jquery来定位
2007/02/20 Javascript
Span元素的width属性无效果原因及解决方案
2010/01/15 Javascript
JS date对象的减法处理实现代码
2010/12/28 Javascript
Js实现当前点击a标签变色突出显示其他a标签回复原色
2013/11/27 Javascript
jquery如何通过name名称获取当前name的value值
2013/12/20 Javascript
showModalDialog模态对话框的使用详解以及浏览器兼容
2014/01/11 Javascript
jquery实现ajax提交form表单的方法总结
2014/03/03 Javascript
JS实现一个按钮的方法
2015/02/05 Javascript
JavaScript中的pow()方法使用详解
2015/06/15 Javascript
JavaScript中this的四个绑定规则总结
2016/09/26 Javascript
jQuery实现简单的回到顶部totop功能示例
2017/10/16 jQuery
教你用Cordova打包Vue项目的方法
2017/10/17 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
2018/04/23 jQuery
socket在egg中的使用实例代码详解
2019/05/30 Javascript
ES6 Promise对象概念及用法实例详解
2019/10/15 Javascript
[01:46]2020完美世界全国高校联赛秋季赛报名开启
2020/10/15 DOTA
videocapture库制作python视频高速传输程序
2013/12/23 Python
python编程实现归并排序
2017/04/14 Python
浅谈numpy中linspace的用法 (等差数列创建函数)
2017/06/07 Python
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
PyQt5每天必学之日历控件QCalendarWidget
2018/04/19 Python
python实现随机漫步算法
2018/08/27 Python
django模板结构优化的方法
2019/02/28 Python
win10下安装Anaconda的教程(python环境+jupyter_notebook)
2019/10/23 Python
Python hashlib模块实例使用详解
2019/12/24 Python
python利用platform模块获取系统信息
2020/10/09 Python
班级文化标语
2014/06/23 职场文书
2016大学生优秀志愿者事迹材料
2016/02/25 职场文书
八年级作文之感悟亲情
2019/11/20 职场文书