Вопрос

Я пытаюсь сделать эквивалент следующего SQL в Django:

ВЫБЕРИТЕ * У кандидата, ГДЕ date_out - date_in >= 1 И date_out - date_in <= 6

Я могу сделать это как НЕОБРАБОТАННЫЙ sql-запрос, но это становится неприятным при работе с RawQuerySet вместо обычного объекта QuerySet, поскольку я хотел бы иметь возможность фильтровать его позже в коде.

Это было полезно?

Решение

Вы можете использовать extra() метод и пройти в where Аргумент ключевого слова. Значение where должен быть список, который содержит SQL WHERE пункт запроса выше. Я проверил это с PostgreSQL 8.4, и это то, что он выглядел в моем случае:

q = Applicant.objects.extra(where = ["""date_part('day', age(date_out, date_in)) >= 1 and
      date_part('day', age(date_out, date_in)) <= 6"""])

Это вернет вам действительный QuerySet экземпляр.

Другие советы

Я столкнулся с проблемой того, что Django изначально не поддерживает Datediff (и другие эквиваленты базы данных), и необходимо было использовать такую функцию много раз для конкретного проекта.

При дальнейшем чтении стало ясно, что реализация вычисления интервала между двумя датами сильно отличается в разных вариантах использования основных баз данных.Вероятно, именно поэтому в Django пока нет собственной функции абстракции.Итак, я написал свою собственную функцию Django ORM для datediff:

Видишь: репозиторий mike-db-tools на Github

Вы увидите различный синтаксис между серверными частями базы данных, написанный в docstrings для соответствующих баз данных.Datediff поддерживает sqlite, MySQL / MariaDB, PostgreSQL и Oracle.

Использование (Django 1.8+):

from db_tools import Datediff

# Define a new dynamic fields to contain the calculated date difference
applicants = Applicant.objects.annotate(
    days_range=Datediff('date_out','date_in', interval='days'),
)

# Now you can use this dynamic field in your standard filter query
applicants = applicants.filter(days_range__gte=1, days_range__lte=6)

Я действительно довольно дерганый, когда дело доходит до моего кода, поэтому я призываю вас разветвляться и совершенствоваться.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top