Рассчитать количество дней в году с помощью Django (queryset) - postgres - PullRequest
1 голос
/ 21 мая 2019

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

Я использую:

Django - 1.11.7
Postgres - 9.4

Вот мои модели.py:

class Leave(models.Model):
    leavedatefrom = models.DateField()
    leavedateto = models.DateField()

Пример для иллюстрациивопрос:

leaves taken in 1 year (01/01/2019 - 31/12/2019)

record 1: (leavedatefrom)01/02/2019 - (leavedateto)05/02/2019 ===> 5 days
record 2: (leavedatefrom)10/05/2019 - (leavedateto)12/05/2019 ===> 3 days

Total days = 5 + 3 = 8 days

Как рассчитать в Django количество дней периодов в базе данных в году?В основном я хочу получить 8 дней в приведенном выше примере.

Ответы [ 3 ]

3 голосов
/ 21 мая 2019

Я думаю, что немного опоздал. Вы можете получить сумму дней в одном запросе SQL

from django.db.models import F, IntegerField, ExpressionWrapper, Sum

Leave.objects.filter(...).annotate(
    diff_date_in_integer=ExpressionWrapper(F('leavedateto') - F('leavedatefrom'), output_field=IntegerField())
).annotate(
    diff_date_in_days=ExpressionWrapper(F('diff_date_in_integer') / (1000000 * 60 * 60 * 24), output_field=IntegerField())).aggregate(
    sum=Sum('diff_date_in_days'))

В предложении filter(...) можно добавить условия фильтрации, такие как datetime или user specific data


Описание

  1. комментирует разницу между leavedateto и leavedatefrom в формате "целое число" (в аннотированном поле diff_date_in_integer) )
  2. Преобразовал данные diff_date_in_integer в days
  3. используя aggregate() функцию и Sum() функцию DB, мы находим общее количество дней.
0 голосов
/ 21 мая 2019

Вы можете сделать запрос, чтобы получить все релевантные листы за год, используя gte и lte django lookup. Например:

import datetime
leaves = Leave.objects.filter(
    leavedatefrom__gte=datetime.date(2019, 1, 1),
    leavedateto__lte=datetime.date(2019, 12, 31)
)

А затем обойдите все листья и вычислите дельту дней между ними и сложите ее в другую переменную:

total_days = 0
for leave in leaves:
    total_days += (leave.leavedateto - leave.leavedatefrom).days
print total_days

См. Как рассчитать количество дней между двумя указанными датами? для получения более подробной информации и опций для расчета диапазонов дат.

EDIT: Одна из оптимизаций, которую можно выполнить, если вы не хотите использовать БД на каждой итерации, - это использовать django values_list():

leaves = Leave.objects.filter(
    leavedatefrom__gte=datetime.date(2019, 1, 1),
    leavedateto__lte=datetime.date(2019, 12, 31)
).values_list('leavedatefrom', 'leavedateto')

total_days = 0
for leavedateto, leavedatefrom in leaves:
    total_days += (leavedateto - leavedatefrom).days
print total_days
0 голосов
/ 21 мая 2019

Ниже приведен наивный подход к получению списка периодов.

Получите все записи об отпуске из системы и для каждой записи определите период времени.

leaves = Leave.objects.filter(leavedatefrom__gte=datetime.date(2019, 1, 1), leavedateto__lte=datetime.date(2019, 12, 31

for leave in leaves:
    days = (leave.leavedatefrom.date() - leave. leavedateto.date()).days()
    period_list.append(days)
total_leaves = sum(period_list)
...