Подтвердить что ты не робот

Как моя модель django DateField добавит 30 дней к предоставленному значению?

как следует из названия. Я хочу добавить 30 дней в поле DateField. Это автоматически заполняется при создании записи с помощью auto_now_add=True

Любые идеи, как это сделать?

Спасибо

4b9b3361

Ответ 1

//Обновление

Комментарий по оригинальному сообщению заставил меня задуматься. Я думаю, это лучшее решение:

from datetime import datetime, timedelta

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

//2. Обновить

Если вы хотите определить атрибут модели, который содержит количество дней, которые нужно добавить, вам нужно будет переопределить метод сохранения. До сих пор я не мог придумать более простой способ.

Решение:

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

Как уже было показано, вы должны переопределить метод сохранения моделей.

Пример:

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

Это не лучший способ для меня, так как вам нужно сохранить модель дважды. Но использование auto_now_add требует, чтобы вы сохранили модель сначала до создания экземпляра datetime для mydate.

Другой подход, который требует только одного сохранения:

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 the first time the model is saved
    if not self.id:
      self.mydate = datetime.now() + d
      super(MyModel, self).save()

Надеюсь, что это помогло!

Ответ 2

Нет необходимости реализовывать пользовательский метод сохранения.

Также делать это 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)

Ответ 3

Использовать Pythons 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 и сделайте так, как это делаетGuru. Информацию об переопределении save() также можно найти в документации Django.

Ответ 4

Отмените сохранение в модели и при сохранении проверьте, заполнено ли 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)