Я хотел бы отфильтровать аннотацию с помощью Django ORM. Многие из статей, которые я нашел здесь ТАК достаточно устарели, нацеливание Джанго обратно в 1,2 до 1,4 дней:Современные методы фильтрации аннотации Django?
- Filtering only on Annotations in Django - этот вопрос с 2010 года предлагает использовать в
extra
положение, которое не рекомендованное официальные документы Джанго - Django annotation with nested filter - Подобные предложения предусмотрены в этом вопросе с 2011.
Django 1.8 добавляет conditional aggregation, что кажется, что я мог бы, но я не могу вполне понять синтаксис, который я В конце концов, мне нужно. Вот мои модели и сценарии я пытаюсь достичь (я упростил модели для краткости):
class Project(models.Model):
name = models.CharField()
... snip ...
class Milestone_meta(models.Model):
name = models.CharField()
is_cycle = models.BooleanField()
class Milestone(models.Model):
project = models.ForeignKey('Project')
meta = models.ForeignKey('Milestone_meta')
entry_date = models.DateField()
Я хочу, чтобы каждый Project
(со всеми полями), наряду с Max(entry_date)
и Min(entry_date)
для каждого связанного Milestone
, но только для тех Milestone
записей, у которых Milestone_meta
имеет флаг is_cycle
, равный True. Другими словами:
- Для каждой записи проекта дайте мне максимальную и минимальную дату входа в Milestone, но только если соответствующий флаг Milestone_meta имеет заданный флаг, равный True.
На данный момент я получаю список проектов, а затем получать Max
и Min
Вехи в цикле, в результате попаданий + 1 базы данных N (который становится медленным, как и следовало ожидать):
pqs = Projects.objects.all()
for p in pqs:
(theMin, theMax) = getMilestoneBounds(p)
# Use values from p and theMin and theMax
...
def getMilestoneBounds(pid):
mqs = Milestone.objects.filter(meta__is_cycle=True)
theData = mqs.aggregate(min_entry=Min('entry_date'),max_entry=Max('entry_date'))
return (theData['min_entry'], theData['max_entry'])
Как я могу уменьшить это до одного или двух запросов?
Я бы сказал, что это определенно случай, когда нужно использовать дополнительный или даже необработанный sql. – e4c5
Документы показывают, что 'extra' в конечном итоге будет устаревшим. В идеале я бы хотел в какой-то степени использовать что-то, что в будущем доказано. –
ну, то используйте более мощные и даже лучше сырые sql – e4c5