1. ホーム
  2. django

[解決済み] Django のモデルフィールドのデフォルト値を関数コール/callable に設定する方法 (例: モデルオブジェクトの生成時刻からの相対的な日付)。

2022-09-13 01:44:19

質問

編集しました。

Django のフィールドのデフォルトを、新しいモデルオブジェクトが作成されるたびに評価される関数に設定するにはどうすればよいですか?

以下のようなことをしたいのですが、このコードでは、モデルオブジェクトが作成されるたびにコードを評価するのではなく、一度評価され、モデルオブジェクトが作成されるたびに同じ日付にデフォルトを設定することを除けば。

from datetime import datetime, timedelta
class MyModel(models.Model):
  # default to 1 day from now
  my_date = models.DateTimeField(default=datetime.now() + timedelta(days=1))





ORIGINALです。

関数のパラメータにデフォルト値を作成したいのですが、これは動的で、関数が呼び出されるたびに呼び出され、設定されます。 どのようにすればよいのでしょうか? 例.

from datetime import datetime
def mydate(date=datetime.now()):
  print date

mydate() 
mydate() # prints the same thing as the previous call; but I want it to be a newer value

具体的には、Djangoでやりたい、など。

from datetime import datetime, timedelta
class MyModel(models.Model):
  # default to 1 day from now
  my_date = models.DateTimeField(default=datetime.now() + timedelta(days=1))

どのように解決するのですか?

この質問は見当違いです。 Django でモデルフィールドを作成するとき、関数を定義しているわけではないので、関数のデフォルト値は関係ありません。

from datetime import datetime, timedelta
class MyModel(models.Model):
  # default to 1 day from now
  my_date = models.DateTimeField(default=datetime.now() + timedelta(days=1))

この最後の行は関数を定義しているのではなく、クラスのフィールドを作成するために関数を呼び出しているのです。

この場合 datetime.now() + timedelta(days=1) は一度だけ評価され、デフォルト値として保存されます。

PRE Django 1.7

Django は [デフォルトとして callable を渡すことができます][1] 、そして、あなたが望むように、毎回 callable を起動します。

from datetime import datetime, timedelta
class MyModel(models.Model):
  # default to 1 day from now
  my_date = models.DateTimeField(default=lambda: datetime.now() + timedelta(days=1))

Django 1.7+

Django 1.7 以降、デフォルト値として lambda を使うことは推奨されないことに注意してください (@stvnw のコメントを参照)。正しい方法は、関数を宣言することです。 の前に を宣言し、それを arg という名前の default_value で callable として使うことです。

from datetime import datetime, timedelta

# default to 1 day from now
def get_default_my_date():
  return datetime.now() + timedelta(days=1)

class MyModel(models.Model):
  my_date = models.DateTimeField(default=get_default_my_date)

詳細は以下の@simanasの回答で。 [1]: https://docs.djangoproject.com/en/dev/ref/models/fields/#default