Django выбирает объекты модели на основе времени с интервалом на самой модели - PullRequest
3 голосов
/ 14 ноября 2009

Я пытаюсь получить все просроченные объекты для модели в моем приложении Django.

Модель выглядит так:

MyModel(models.Model):
    owner = models.ForeignKey(User)
    last_check = models.DateTimeField(blank=True, null=True)
    interval = models.IntegerField(default=1800)

Мне нужно получить все подходящие объекты, где last_check раньше, чем сейчас, минус интервал проверки, чтобы определить, нужно ли проверять объект снова.

Нет проблем, если я использую статический интервал:

time_diff = datetime.now() - timedelta(seconds=1800)
MyModel.object.filter(last_check__lte=time_diff)

Но когда интервал находится на самой модели, я не могу понять, как это сделать. Вот что я попробовал:

objects_to_check = MyModel.objects.filter(
                                        last_check__isnull=False
                                    ).filter(
                                        last_check__lte=datetime.now() - timedelta(seconds=F('interval'))
                                    )

Но это не сработало совсем, только дало мне следующую ошибку

unsupported type for timedelta seconds component: F

Есть идеи, как это решить?

Ответы [ 3 ]

3 голосов
/ 14 ноября 2009

Хм ... Я не уверен, что вы можете изменить значение искомого поля. База данных все равно должна сначала извлечь значение, применить к нему функцию timedelta, а затем выполнить сравнение.

Я думаю, что вам, возможно, придется переосмыслить свою архитектуру ... но я могу ошибаться. Возможно, вместо сохранения last_check, сохраните свойство expired , которое вы можете проверить напрямую:

MyModel.objects.filter(expired__lte=current_date)

, а затем при обновлении модели:

def save(self):
    self.expired = datetime.now() + self.interval;

или что-то в этом роде.

0 голосов
/ 13 сентября 2010

поддержка такого рода запросов находится в разработке: http://code.djangoproject.com/ticket/10154

0 голосов
/ 15 ноября 2009

F объект обозначает ссылку на поле модели в запросе SQL , поэтому вы не можете инициализировать объект Python с ним. Вы можете написать запрос к базе данных, используя метод extra или просто отфильтровать их на уровне Python:

filter(lambda x: x.last_check <= datetime.now() - timedelta(seconds = x.interval), MyModel.objects.all())
...