Аннотировать набор запросов со средней разницей в датах?(Джанго) - PullRequest
11 голосов
/ 28 июня 2010

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

Скажем, моя модель такова (псевдоджанго-код):

Event
  type = ForeignKey(EventType)
  name = CharField
  date_start = DateField
  date_end = DateField

EventType
  name = CharField

То, что я хочу знать, это средняя продолжительность каждого типа событий.Теперь я вычисляю среднюю продолжительность, когда создается новое событие (метод сохранения), и оно сохраняется в столбце Average_duration в EventType.Проблема с этим подходом заключается в том, что я не могу ответить на вопросы типа «какова была средняя продолжительность событий типа X, в течение года Y ».Таким образом, вместо добавления дополнительных столбцов для ответов на подобные вопросы, я бы предпочел, чтобы это было сделано в режиме реального времени.

Можно ли это сделать путем аннотирования набора запросов?Сначала я должен был бы получить различия в дате для каждого типа события, затем придумать их среднее значение, а затем, я полагаю, аннотировать набор запросов Event с этим средним значением.

Ответы [ 3 ]

31 голосов
/ 30 сентября 2015

Просто обновление. В Django> = 1.8 можно сделать:

from django.db.models import F, ExpressionWrapper, fields

duration = ExpressionWrapper(F('date_end') - F('date_start'), output_field=fields.DurationField())

events_with_duration = Event.objects.annotate(duration=duration)

, после чего вы можете запускать запросы вроде:

events_with_duration.filter(duration__gt=timedelta(days=10))
1 голос
/ 28 июня 2010

Вам потребуется создать набор запросов с помощью метода extra , чтобы добавить разницу в дате в каждую строку

Затем использовать метод aggregate для вычисления среднегодля только что добавленного вами столбца:

Будьте осторожны, этот метод медленный и не масштабируется.Хранение вычисленного значения в event_type - это ваш лучший выбор.

1 голос
/ 28 июня 2010

Я думаю, что вам лучше всего создать представление SQL со столбцом date_end - date_start, создать модель django для этого представления, и тогда вы сможете запрашивать представление и аннотировать его, как хотите. Я сделал это с моделями, похожими на ваши, и, возможно, я мог бы извлечь для вас какой-нибудь интересный код, если вам нужно.

...