DjangoでこのSQLと同等の方法はありますか?
UPDATE table SET timestamp=NOW() WHERE ...
特に、サーバーの組み込み関数を使用してdatetimeフィールドを設定し、クライアントマシンの時刻ではなく、データベースが実行されているサーバーからシステム時刻を取得したい。
生のSQLを直接実行できることは知っていますが、データベースには現在の日時を取得するためのさまざまな機能があるため、よりポータブルなソリューションを探しています。
編集:auto_nowパラメーターに言及した人はほとんどいません。これは、特定の状況でのみ日時を更新したいのに対し、すべての変更で日時を更新します。
J0kerが言ったように、タイムスタンプの自動更新が必要な場合は、_auto_now
_オプションを使用します。例えば。 date_modified = models.DateTimeField(auto_now=True)
。
または、手動で行う場合は、python datetime.now()
_)を使用した単純な割り当てではありませんか?
_from datetime import datetime
obj.date_modified = datetime.now()
_
受け入れられた答えは時代遅れです。これが現在の最も簡単な方法です:
>>> from Django.utils import timezone
>>> timezone.now()
datetime.datetime(2018, 12, 3, 14, 57, 11, 703055, tzinfo=<UTC>)
この問題の解決方法を次に示します。それが誰かの時間を節約することを願っています:
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()
データベース関数 Now starting Django 1.9:
from Django.db.models.functions import Now
Model.objects.filter(...).update(timestamp=Now())
次のようなものを使用して、データベースの現在の時間の使用を表すカスタム値を作成できます。
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()
私の微調整したコードは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()
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)
外部サーバー(Djangoアプリケーション)をホストするサーバーではない)から日時を取得したい場合、使用するデータタイムのために手動でペグする必要があります。 select now();
などのSQLコマンド、またはssh user@Host "date +%s"
などのSSH上の何か。
たぶん、あなたはドキュメントを調べる必要があります:
モデルフィールド:DateField
オプション「auto_now」は、まさにあなたが探しているものです。 DateTimeFieldで使用することもできます。モデルを保存するたびにDateTimeを更新します。そのため、DateTimeFieldにこのオプションを設定すると、データレコードを取得し、時間を正しく設定するために再度保存するのに十分なはずです。