如何在Django中将DateTimeField设置为零



我想创建一个DateTime为0000-00-00 00:00:00的对象,所以当我按ASC顺序检查日期时,会首先检查新对象。

对于django 1.9,使用以下字段:

from django.db import models  
class NullDateTimeField(models.DateTimeField):
    def get_db_prep_value(self, value, connection, prepared=False):
        # Casts datetimes into the format expected by the backend
        if not prepared:
            value = self.get_prep_value(value)
        # Use zeroed datetime instead of NULL
        if value is None:
            return  "0000-00-00 00:00:00"
        else:
            return connection.ops.adapt_datetimefield_value(value)

基于django DateTimeField源。

您想要的是"epoch":

历元日期,时间戳1970-01-01 00:00:00+00(Unix系统时间零点)

>>> import datetime
>>> datetime.datetime.utcfromtimestamp(0)
datetime.datetime(1970, 1, 1, 0, 0)

除非日期0000-00-00 00:00:00实际上对您有意义,否则您不应该将其用作"特殊"值。您应该使用NULL,例如

然而,我不认为评论中关于NULL默认以升序排列第一的说法是正确的,因为,让我们尝试这样的模型:

class Log(Model):                                                                                                           
    timestamp = DateTimeField(null=True, default=None)                                                                      
    def __str__(self):                                                                                                      
        return str(self.timestamp) 

我创建了一些此类对象:

In [21]: Log.objects.all()
Out[21]: [<Log: None>, <Log: 2015-12-28 12:33:17.464426>, <Log: 2015-12-28 12:35:52.313617>, <Log: None>]

上面的内容没有排序,所以它们在数据库中按基本顺序出现。

以下是ASC排序:

In [22]: Log.objects.order_by('timestamp')                                                                                  
Out[22]: [<Log: 2015-12-28 12:33:17.464426>, <Log: 2015-12-28 12:35:52.313617>, <Log: None>, <Log: None>]

正如你所看到的,NULL在我的ASC排序中排名最后。我使用PostgreSQL进行这个测试。

以下是DSC排序:

In [23]: Log.objects.order_by('-timestamp')
Out[23]: [<Log: None>, <Log: None>, <Log: 2015-12-28 12:35:52.313617>, <Log: 2015-12-28 12:33:17.464426>]

但是,您可以使用extra()显式指定要如何对NULL进行排序:

In [24]: Log.objects.extra(select={'timestamp_is_null': "timestamp is NULL"}, order_by=['-timestamp_is_null', 'timestamp'])
Out[24]: [<Log: None>, <Log: None>, <Log: 2015-12-28 12:33:17.464426>, <Log: 2015-12-28 12:35:52.313617>]

这是一个更可读的我的片段

Log.objects.extra(
    select={'timestamp_is_null': "timestamp is NULL"},
    order_by=['-timestamp_is_null', 'timestamp']
)

此测试的版本:

  • PostgreSQL 9.4.5
  • Django 1.8.4

最新更新