Django: использование аргументов F в datetime.timedelta внутри запроса

Используя синтаксис модели Django, если я сделаю это:

ThatModel.objects.filter(
    last_datetime__lte=now + datetime.timedelta(seconds=F("interval")))

Я получил:

TypeError: unsupported type for timedelta days component: ExpressionNode

Есть ли способ заставить это работать с чистым синтаксисом Django (и не анализировать все результаты с помощью Python)?


person Synthead    schedule 10.06.2014    source источник
comment
У меня есть несколько вопросов, какой тип объекта now, является ли интервал целочисленным полем и каково его значение?? Спасибо   -  person ruddra    schedule 10.06.2014
comment
now — это объект datetime.datetime. Поле interval является IntegerField, и его значение равно 5.   -  person Synthead    schedule 10.06.2014
comment
Вы можете сделать это. Пожалуйста, обратитесь к этому моему ответу.   -  person Naresh Chaudhary    schedule 22.02.2017


Ответы (2)


Из документов Джанго:

Django предоставляет F-выражения для таких сравнений. Экземпляры F() действуют как ссылка на поле модели в запросе. Затем эти ссылки можно использовать в фильтрах запросов для сравнения значений двух разных полей в одном и том же экземпляре модели.

Это означает, что вы можете использовать F() для сравнения внутри запросов. F() возвращает ссылку, поэтому, когда вы используете ее в качестве параметра для объекта timedelta, вы получаете ошибку ExpressionNode. Вы можете ознакомиться с документацией. Вы можете проверить исходный код F()

Для вашего решения вы можете проверить это: DateModifierNode или просто сохраните значение interval в другом месте, а затем передайте его как параметр timedelta.

person ruddra    schedule 10.06.2014
comment
Этот ответ больше недействителен - задал новый вопрос здесь: django" title="что является заменой datemodifiernode в новых версиях django"> stackoverflow.com/questions/38703016/ - person Chozabu; 01.08.2016

Просто избегайте F-невежества timedelta

filter знает о F, а timedelta нет. Хитрость заключается в том, чтобы исключить F из списка аргументов timedelta:

ThatModel.objects.filter(
    last_datetime__lte=now + datetime.timedelta(seconds=1)*F("interval"))

Этот будет работать с PostgreSQL, но, увы, не с SQlite .

person Lutz Prechelt    schedule 19.09.2017