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

kef*_*hou 45 python database django

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

UPDATE table SET timestamp=NOW() WHERE ...
Run Code Online (Sandbox Code Playgroud)

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

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

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

jsz*_*jsz 55

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

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

from datetime import datetime

obj.date_modified = datetime.now()
Run Code Online (Sandbox Code Playgroud)

  • 服务器是指托管数据库的机器,客户端是运行python/django并从数据库访问数据的机器.这里的用例是当多个客户端机器正在访问数据库并更新时间戳时,如果客户端的系统时间没有同步(由于缺乏权限有时不可能),那么很难找出哪个顺序条目已更新 - 这就是为什么最好在服务器上使用系统时间,以便时间戳来自同一时钟. (7认同)
  • Auto_now在我不想要的每次更新时更新datetime字段.并且python的datetime.now()将在客户端获得当前的日期时间,但不能保证它甚至接近服务器上的日期时间. (4认同)
  • 现在我明白了.您应该将其添加到原始问题,因为我不认为它是明确的,您指的是数据库服务器. (3认同)
  • datetime.now() 如何使用客户端的日期时间?视图中的所有 Python 代码都在服务器上执行,因此它当然使用服务器的日期时间。 (2认同)

And*_*ade 31

接受的答案已过时.这是当前和最简单的方法:

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


小智 9

你可以使用数据库函数现在启动Django 1.9:

from django.db.models.functions import Now
Model.objects.filter(...).update(timestamp=Now())
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 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)
Run Code Online (Sandbox Code Playgroud)

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

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

    or:

book.created_on = DBNow()
book.save()
Run Code Online (Sandbox Code Playgroud)


Dav*_*gan 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
Run Code Online (Sandbox Code Playgroud)

然后,为了能够在DateTimeField上使用DatabaseNow:

databaseDependentPatch(models.DateTimeField)
Run Code Online (Sandbox Code Playgroud)

然后反过来最终允许你做一个漂亮和干净:

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

operation = # Some previous operation
operation.dateTimeCompleted = DatabaseNow()
operation.save()
Run Code Online (Sandbox Code Playgroud)


j0k*_*ker 1

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

选项“auto_now”可能正是您正在寻找的。您还可以将其与 DateTimeField 一起使用。每次保存模型时它都会更新日期时间。因此,通过为 DateTimeField 设置该选项,检索数据记录并再次保存以设置正确的时间应该足够了。