web-dev-qa-db-ja.com

Django model DateFieldでは、指定された値に30日を追加できますか?

タイトルが示すように。 DateFieldフィールドに30日を追加します。これは、auto_now_add=Trueを使用したレコードの作成時に自動入力されます

これを行う方法についてのアイデアはありますか?

ありがとう

24
dotty

//更新

元の投稿の下のコメントは私に考えさせられました。これが今のところ最良の解決策だと思います:

from datetime import datetime, timedelta

class MyModel(models.Model):
   mydate = models.DateTimeField(default=datetime.now()+timedelta(days=30))

// 2.更新

追加する必要がある日数を保持するモデル属性を定義する場合は、saveメソッドをオーバーライドする必要があります。これまでのところ、もっと簡単な方法を思いつくことはできませんでした。

解決:

class MyModel(models.Model):
  mydate = models.DateTimeField(editable=False)
  daysadded = models.IntegerField()

  def save(self):
    from datetime import datetime, timedelta
    d = timedelta(days=self.daysadded)

    if not self.id:
      self.mydate = datetime.now() + d
      super(MyModel, self).save()

すでになっているように、モデルのsaveメソッドをオーバーライドする必要があります。

例:

class MyModel(models.Model):
  mydate = models.DateTimeField(auto_now_add=True)      

  def save(self):
    from datetime import timedelta
    d = timedelta(days=30)

    // only add 30 days if it's the first time the model is saved
    if not self.id:
      // not saving the model before adding the timedelta gave me errors 
      super(MyModel, self).save()

      self.mydate += d

      // final save
      super(MyModel, self).save()

モデルを2回保存する必要があるため、これは私にとって最良の方法ではありません。ただし、auto_now_addを使用するには、mydateのdatetimeインスタンスが作成される前に、まずモデルを保存する必要があります。

保存が1つだけ必要な別のアプローチ:

class MyModel(models.Model):
  mydate = models.DateTimeField(editable=False) // editable=False to hide in admin

  def save(self):
    from datetime import datetime, timedelta
    d = timedelta(days=30)

    // only add 30 days if it's the first time the model is saved
    if not self.id:
      self.mydate = datetime.now() + d
      super(MyModel, self).save()

お役に立てば幸いです。

42
Jens

カスタムのsaveメソッドを実装する必要はありません。

また、これを行うことはdefault=datetime.now()+timedelta(days=30)は完全に間違っています! Djangoのインスタンスを起動すると評価されます。 Apacheを使用する場合、Apacheはいくつかの構成でDjangoアプリケーションを要求ごとに取り消すため、おそらく機能しますが、それでも、いつかコードを調べて理解しようとする自分を見つけることができますなぜこれが期待どおりに計算されないのか。

これを行う正しい方法は、呼び出し可能なオブジェクトをデフォルトの引数に渡すことです。 datetime.today関数またはカスタム関数を使用できます。その後、新しいデフォルト値を要求するたびに評価されます。

def get_deadline():
    return datetime.today() + timedelta(days=20)

class Bill(models.Model):
    name = models.CharField(max_length=50)
    customer = models.ForeignKey(User, related_name='bills')
    date = models.DateField(default=datetime.today)
    deadline = models.DateField(default=get_deadline)
56
Simanas

Pythonを使用 timedelta

_from datetime import timedelta
d = timedelta(days=30)

# object is your current instance of the model
object.yourdatefield += d
# or this because I am not sure whether the previous works
object.yourdatefield = object.yourdatefield + d

object.save()
_

そして Djangoドキュメント から:

DateField
日付は、Python= _datetime.date_インスタンスによって表されます。

オブジェクトの作成に30日を追加する場合は、_auto_now_add=True_を忘れて、beingGuruの提案どおりに実行してください。 save()のオーバーライドに関する情報は Djangoのドキュメント にもあります。

3
Felix Kling

モデルの保存を上書きし、保存中にpkが入力されているかどうかを確認します。

>>> from datetime import datetime
>>> from datetime import timedelta
>>> cur_date = datetime.now()
>>> cur_date
datetime.datetime(2010, 2, 4, 5, 0, 24, 437405)
>>> cur_date+timedelta(days=30)
datetime.datetime(2010, 3, 6, 5, 0, 24, 437405)
1
Lakshman Prasad