Django中的日期处理注意事项和自定义时间格式转换

栏目: Python · 发布时间: 6年前

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

我们在用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有关):

![可能的默认日期格式]

Django中的日期处理注意事项和自定义时间格式转换

如果不习惯这种格式,自己定义显示格式的配置如下,更改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 >;

Available format strings,部分截图:

Django中的日期处理注意事项和自定义时间格式转换

Django中的日期处理注意事项和自定义时间格式转换

format stringsDjango中的日期处理注意事项和自定义时间格式转换

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


以上所述就是小编给大家介绍的《Django中的日期处理注意事项和自定义时间格式转换》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网站分析实战

网站分析实战

王彦平 吴盛峰 / 电子工业出版社 / 2013-1 / 59.00元

《网站分析实战:如何以数据驱动决策,提升网站价值》由王彦平、吴盛峰著。目前,越来越多的网站开始重视数据,并期望从中发现新的机会,不管你是做网络营销、互联网产品设计、电子商务运营、个人站点运营维护,我们都希望从数据中寻找有价值的结论,并且指导公司管理层的决策,最终创造更大的网站价值。《网站分析实战:如何以数据驱动决策,提升网站价值》以通俗易懂的方式来讲解网站分析所需掌握的知识,剖析日常工作中遇到的问......一起来看看 《网站分析实战》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码