web-dev-qa-db-ja.com

django DateTimeFieldをサーバーの現在時刻に設定

DjangoでこのSQLと同等の方法はありますか?

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

特に、サーバーの組み込み関数を使用してdatetimeフィールドを設定し、クライアントマシンの時刻ではなく、データベースが実行されているサーバーからシステム時刻を取得したい。

生のSQLを直接実行できることは知っていますが、データベースには現在の日時を取得するためのさまざまな機能があるため、よりポータブルなソリューションを探しています。

編集:auto_nowパラメーターに言及した人はほとんどいません。これは、特定の状況でのみ日時を更新したいのに対し、すべての変更で日時を更新します。

43
kefeizhou

J0kerが言ったように、タイムスタンプの自動更新が必要な場合は、_auto_now_オプションを使用します。例えば。 date_modified = models.DateTimeField(auto_now=True)

または、手動で行う場合は、python datetime.now()_)を使用した単純な割り当てではありませんか?

_from datetime import datetime

obj.date_modified = datetime.now()
_
54
jsz

受け入れられた答えは時代遅れです。これが現在の最も簡単な方法です:

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

この問題の解決方法を次に示します。それが誰かの時間を節約することを願っています:

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()
8
Chris

データベース関数 Now starting Django 1.9:

from Django.db.models.functions import Now
Model.objects.filter(...).update(timestamp=Now())
7
tvorog

次のようなものを使用して、データベースの現在の時間の使用を表すカスタム値を作成できます。

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
David Q Hogan

私の微調整したコードは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()
4
Kukosk

Python Djangoプラグインモジュールを作成しました。これにより、特定の場合にDateTimeFieldオブジェクトでCURRENT_TIMESTAMPの使用を制御できます(以下のusageを参照) )およびauto_nowおよびauto_now_add列に対して自動的に。

Django-pg-current-timestamp

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)
3
Jay Taylor

外部サーバー(Djangoアプリケーション)をホストするサーバーではない)から日時を取得したい場合、使用するデータタイムのために手動でペグする必要があります。 select now();などのSQLコマンド、またはssh user@Host "date +%s"などのSSH上の何か。

2
Mel Boyce

たぶん、あなたはドキュメントを調べる必要があります:
モデルフィールド:DateField

オプション「auto_now」は、まさにあなたが探しているものです。 DateTimeFieldで使用することもできます。モデルを保存するたびにDateTimeを更新します。そのため、DateTimeFieldにこのオプションを設定すると、データレコードを取得し、時間を正しく設定するために再度保存するのに十分なはずです。

1
j0ker