поскольку заголовок предлагает. Я хочу добавить 30 дней к DateField
поле. Это автоматически заполненный на создании рекордного использования auto_now_add=True
Какие-либо идеи, как пойти о выполнении этого?
Спасибо
, естественно заключить в капсулу «Периоды» с Образцом Команды (который является в основном, что вы сделали). Но вы сталкиваетесь с двумя проблемами: -
1) Вы должны перекомпилировать, чтобы добавить больше периодов
Вы можете перечислить все возможные действие, которое возможно для периода взять, затем определить периоды в некоторых внешний формат (XML, база данных), загружается в приложение на запуск. Западные RPG, как правило, кодируются как это - "период" состоит из "Применить эффект периода # 1234 с параметром 1000 ", «play animation # 2345» и т.д.
Вы можете открыть для своего игрового объекта сценарий язык и сценарий периодов (можно также объединить это с первой идеей, чтобы в большинстве случаи, когда написанные по сценарию периоды просто вызывают предопределенные эффекты в коде). Поединок планезвалкеров (игра M: TG на X-Box 360) была написана широко с этот подход
Или вы можете просто жить с ним (я делаю...)
2) Что происходит, когда ваш период цель не существо?
Если вы выставляете свое игровое имущество своим периодам сценариям, это не проблема, потому что ваши сценарии могут делать все, что им нравится, в контексте того, что вы выставляете.
В противном случае лучше всего создать общий тип.
Я обычно делаю что-то вроде следующего (и не только в играх, я также использовал этот тип образца для представления поведения в mutli-agent-системах): -
public interface IEffect<TContext>
{
public void Apply(TContext context);
}
public class SingleTargetContext
{
public Creature Target { get; set; }
}
public class AoEContext
{
public Point Target { get; set; }
}
// etc.
Преимущество этого образца в том, что она действительно гибкая для выполнения тех «странных» вещей, на которые вы часто ожидаете, что периоды смогут сделать, что более фиксированные модели не будут способны. Вы можете делать такие вещи, как связывать их вместе. Вы можете иметь Эффект, который добавляет Эффект Effect к вашей цели - хорошо для того, чтобы сделать что-то вроде Терновая Аура. Для представления буферов можно использовать IReversibleEffect (с дополнительным методом Unapply).
-121--2970308-//Обновление
Комментарий под оригинальным постом заставил меня задуматься. Полагаю, это лучшее решение на данный момент:
from datetime import datetime, timedelta
class MyModel(models.Model):
mydate = models.DateTimeField(default=datetime.now()+timedelta(days=30))
//2. Update
Если требуется определить атрибут модели, содержащий количество дней, которое должно быть добавлено, необходимо переопределить метод сохранения. Пока я не могу придумать более простой способ.
Решение:
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'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()
Это не лучший способ для меня, так как вы должны сохранить модель дважды. Но при использовании 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's the first time the model is saved
if not self.id:
self.mydate = datetime.now() + d
super(MyModel, self).save()
Надежда, которая помогла!
Отмените сохранение модели и во время сохранения проверьте, заполнено ли значение 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)
Используйте 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
A date, представленная на Python экземпляромdatetime.date
.
Если вы хотите добавить 30 дней на создание объекта, забудьте о auto_now_add=True
и сделайте то, что предлагает becomeGuru. Информацию о переопределении save()
также можно найти в документации Django.