django将DateTimeField设置为服务器的当前时间

时间:2011-09-19 01:58:17

标签: python database django

如何在django中执行此SQL的等效操作?

UPDATE table SET timestamp=NOW() WHERE ...

特别是我想使用服务器的内置函数设置datetime字段,以便从运行数据库的服务器获取系统时间,而不是客户端计算机上的时间。

我知道你可以直接执行原始sql,但我正在寻找一种更便携的解决方案,因为数据库具有不同的功能来获取当前的日期时间。

编辑:很少有人提到auto_now param。这会在每次修改时更新日期时间,而我只想在某些情况下更新日期时间。

10 个答案:

答案 0 :(得分:51)

正如j0ker所说,如果要自动更新时间戳,请使用auto_now选项。例如。 date_modified = models.DateTimeField(auto_now=True)

或者如果你想手动完成,不是python datetime.now()的简单任务吗?

from datetime import datetime

obj.date_modified = datetime.now()

答案 1 :(得分:25)

接受的答案已过时。以下是目前最简单的方法:

>>> from django.utils import timezone
>>> timezone.now()
datetime.datetime(2018, 12, 3, 14, 57, 11, 703055, tzinfo=<UTC>)

答案 2 :(得分:8)

以下是我解决这个问题的方法。希望能节省时间:

from django.db import models

class DBNow(object):
    def __str__(self):
        return 'DATABASE NOW()'
    def as_sql(self, qn, val):
        return 'NOW()', {}
    @classmethod
    def patch(cls, field):
        orig_prep_db = field.get_db_prep_value
        orig_prep_lookup = field.get_prep_lookup
        orig_db_prep_lookup = field.get_db_prep_lookup

        def prep_db_value(self, value, connection, prepared=False):
            return value if isinstance(value, cls) else orig_prep_db(self, value, connection, prepared)

        def prep_lookup(self, lookup_type, value):
            return value if isinstance(value, cls) else orig_prep_lookup(self, lookup_type, value)

        def prep_db_lookup(self, lookup_type, value, connection, prepared=True):
            return value if isinstance(value, cls) else orig_db_prep_lookup(self, lookup_type, value, connection=connection, prepared=True)

        field.get_db_prep_value = prep_db_value
        field.get_prep_lookup = prep_lookup
        field.get_db_prep_lookup = prep_db_lookup

# DBNow Activator
DBNow.patch(models.DateTimeField)

然后只使用DBNow()作为需要更新和过滤的值:

books = Book.objects.filter(created_on__gt=DBNow())

    or:

book.created_on = DBNow()
book.save()

答案 3 :(得分:6)

您可以使用数据库函数Now启动Django 1.9:

ReactTable

答案 4 :(得分:5)

您可以使用类似的内容创建自定义值来表示数据库中当前时间的使用:

class DatabaseDependentValue(object):
    def setEngine(self, engine):
        self.engine = engine

    @staticmethod
    def Converter(value, *args, **kwargs):
        return str(value)

class DatabaseNow(DatabaseDependentValue):
    def __str__(self):
        if self.engine == 'django.db.backends.mysql':
            return 'NOW()'
        elif self.engine == 'django.db.backends.postgresql':
            return 'current_timestamp'
        else:
            raise Exception('Unimplemented for engine ' + self.engine)

django_conversions.update({DatabaseNow: DatabaseDependentValue.Converter})

def databaseDependentPatch(cls):
    originalGetDbPrepValue = cls.get_db_prep_value
    def patchedGetDbPrepValue(self, value, connection, prepared=False):
        if isinstance(value, DatabaseDependentValue):
            value.setEngine(connection.settings_dict['ENGINE'])
            return value
        return originalGetDbPrepValue(self, value, connection, prepared)
    cls.get_db_prep_value = patchedGetDbPrepValue

然后能够在DateTimeField上使用DatabaseNow:

databaseDependentPatch(models.DateTimeField)

然后反过来最终会让你做得很干净:

class Operation(models.Model):
    dateTimeCompleted = models.DateTimeField(null=True)
    # ...

operation = # Some previous operation
operation.dateTimeCompleted = DatabaseNow()
operation.save()

答案 5 :(得分:4)

我的调整代码适用于sqlite,mysql和postgresql,并且比提议的解决方案更清晰。

class DBCurrentTimestamp:
    def __str__(self):
        return 'DATABASE CURRENT_TIMESTAMP()'

    def as_sql(self, qn, connection):
        return 'CURRENT_TIMESTAMP', {}

    @classmethod
    def patch(cls, *args):
        def create_tweaked_get_db_prep_value(orig_get_db_prep_value):
            def get_db_prep_value(self, value, connection, prepared=False):
                return value if isinstance(value, cls) else orig_get_db_prep_value(self, value, connection, prepared)

            return get_db_prep_value

        for field_class in args:
            field_class.get_db_prep_value = create_tweaked_get_db_prep_value(field_class.get_db_prep_value)

我在我的models.py文件的末尾激活它,如下所示:

DBCurrentTimestamp.patch(models.DateField, models.TimeField, models.DateTimeField)

并像这样使用它:

self.last_pageview = DBCurrentTimestamp()

答案 6 :(得分:3)

我创建了一个Python Django插件模块,允许您控制CURRENT_TIMESTAMPDateTimeField对象的使用,在特定情况下(参见下面的usage)以及自动适用于auto_nowauto_now_add列。

<强>的django-PG-当前时间戳

GitHub:https://github.com/jaytaylor/django-pg-current-timestamp

PyPi:https://pypi.python.org/pypi/django-pg-current-timestamp

使用示例:

from django_pg_current_timestamp import CurrentTimestamp

mm = MyModel.objects.get(id=1)
mm.last_seen_date = CurrentTimestamp()
mm.save()
## Resulting SQL:
##     UPDATE "my_model" SET "last_seen_date" = CURRENT_TIMESTAMP;

print MyModel.objects.filter(last_seen_date__lt=CURRENT_TIME).count()

MyModel.objects.filter(id__in=[1, 2, 3]).update(last_seen_date=CURRENT_TIME)

答案 7 :(得分:2)

如果您想要来自外部服务器的日期时间(即,不是托管Django应用程序的服务器),您将不得不手动将其挂起以供数据时使用。您可以使用select now();等SQL命令或SSH之类的命令,如ssh user@host "date +%s"

答案 8 :(得分:1)

也许您应该查看文档:
Modelfields: DateField

选项'auto_now'可能正是您要搜索的内容。您也可以将它与DateTimeField一起使用。每次保存模型时,它都会更新DateTime。因此,为DateTimeField设置该选项,它应该足以检索数据记录并再次保存以设置正确的时间。

答案 9 :(得分:0)

在创建表格时,添加数据后要在字段中创建日期的字段将此代码添加到字段

class MyModel(models.Model):
  created_at = models.DateTimeField(auto_now_add=True)
  updated_at = models.DateTimeField(auto_now=True)