web-dev-qa-db-ja.com

Django:timezone.nowとtimezone.now()

プロジェクトをDjango 1.8.2から1.9.7にアップグレード中です。この警告が表示されます。

_WARNINGS:
my_app.my_model.date_available: (fields.W161) Fixed default value provided.
HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. 
If you want to have the current date as default, use `Django.utils.timezone.now
_

My_app/models.pyの行は次のとおりです。

_from Django.utils import timezone
...
class my_model(models.Model):
    ...
    datetime_released = models.DateTimeField(default=timezone.now() )
_

かっこを削除して代わりに使用する場合:

_datetime_released = models.DateTimeField(default=timezone.now )
_

Django警告はなくなります。2つの違いは何ですか?


私のプロジェクトの別の領域では、クエリセットフィルターでtimezone.now()を使用しています。

_def date_available(self):
        return self.filter(date_available__lte = timezone.now())
_

ここで、括弧を削除すると、エラーがスローされます。

_TypeError: expected string or buffer_


必要に応じて括弧を追加/削除することで、これら2つの機能の両方を取得できますが、timezone.now()と_timezone.now_の違いは何ですか。これらの場合に警告/エラーが発生するのはなぜですか?

15
43Tesseracts

In pythonすべてが関数を含むオブジェクトです。これは、関数が変数に影響を与えることができることを意味します。

_>>> from Django.utils import timezone
>>> foo = timezone.now
>>> foo
<function Django.utils.timezone.now>
>>> foo()
datetime.datetime(2016, 7, 7, 9, 11, 6, 489063)
_

関数は呼び出し可能なオブジェクトです:

_>>> callable(foo)
True
>>> callable(foo())
False
_

defaultがcallableを受け取ると、デフォルト値が要求されるたびにcallableが呼び出されます。

一方、defaultを設定する前にtimezone.now()を呼び出すと、値が与えられ、修正されます。次の行は、クラス属性であるため、サーバーの起動時に1回だけ実行されます。

_    datetime_released = models.DateTimeField(default=timezone.now())
_

したがって、timezone.now()は1回だけ実行されます。呼び出し可能な_timezone.now_を渡すと、必要なときにいつでも値を再計算できます。

22
Antoine Pinsard

違いは、_timezone.now_は実行時に実行される呼び出し可能オブジェクトであり、timezone.now()はその関数の出力を返すことです。

_models.DateTimeField_には、呼び出し可能オブジェクトを使用する必要があります。さらに良いことに、単に設定します _auto_now_add_ これはあなたのためにこれを行います:

_datetime_released = models.DateTimeField(auto_now_add=True)
_

一方、フィルターはcallableを受け入れません-値が必要です。したがって、これをフィルターへの引数として渡すときにtimezone.now()を評価する必要があります。

10
solarissmoke

now()は、モデルがロードされると実行され、ロード時に日時オブジェクト/時間文字列を返します。 (したがってDjango警告!)(サーバーの起動時にモデルファイルが完全に実行された場合)

nowはnowメソッドを渡し、クラス/モデルがインスタンス化されたときにのみ実行され、適切なタイミングでタイムスタンプを作成します(正しい方法、ほとんどの人が達成しようとしていること)。

フィルターの例では、フィルター関数が呼び出されたときにのみ呼び出されます。 (now())を実行せずにメソッドにフィードし、必要なdatetimeオブジェクトを生成しない場合。 (エラー、文字列が必要、取得、その他)

1
gtalarico

self.filter(date_available__lte = timezone.now())では、現在の時刻に基づいてDBにクエリを作成します。したがって、文字列形式で必要です。

datetime_released = models.DateTimeField(default=timezone.now)では、デフォルトを現在の時刻に設定します。そのため、そこに文字列を置くことはできません。代わりに、現在の時刻を返すことができる関数を提供します。

1
Arun Ghosh

timezone.now()は、モデルがロードされるときに現在のタイムスタンプを返します。一方、timezone.nowは関数への引数として渡され、オブジェクトが作成されるたびに(クラスのインスタンス化で)呼び出されます

次のコードで

def date_available(self):
    return self.filter(date_available__lte = timezone.now())

関数date_availabeは、self.filterを返すときに関数として解析の関数文字列を必要とします。

1