Есть три модели: Job, WorkItem и DocumentPackage.
У Job есть ForeignKey на WorkItem, а у WorkItem есть ForeignKey на DocumentPackage.
Задача состоит в том, чтобы отфильтровать только те DocumentPackage, в которых у всех WorkItem'ов, Job с самым большим id имеет state=Job.STATE_COMPLETE
def finished(qs):
active_jobs = Job.objects.filter(item=OuterRef('pk')).order_by('-id')
active_items = (
WorkItem.objects.annotate(
active_job_state=Subquery(active_jobs.values('state')[:1])
).filter(
active_job_state=Job.STATE_COMPLETE
)
)
qs = qs.prefetch_related(
Prefetch(
'work_items',
queryset=active_items,
to_attr='active_items',
)
).annotate(
_active=Count('active_items'),
).annotate(
_total=Count('work_items')
)
return qs.filter(_total=F('_active'))
Ошибка возникает при вычислении Count('active_items'):
FieldError: Cannot resolve keyword 'active_items' into field.
Модели (лишние поля убрал):
class Job(models.Model):
STATE_PENDING = 0
STATE_TODO = 1
STATE_PAUSED = 2
STATE_REQUESTED = 3
STATE_IN_PROGRESS = 4
STATE_READY = 5
STATE_COMPLETE = 6
STATE_RETURNED = 7
STATE_ABORTED = 8
STATE_HISTORY = 9
STATE_CHOICES = Choices(
(STATE_PENDING, 'Pending'),
(STATE_TODO, 'ToDo'),
(STATE_PAUSED, 'Paused'),
(STATE_REQUESTED, 'Requested'),
(STATE_IN_PROGRESS, 'InProgress'),
(STATE_READY, 'Ready'),
(STATE_COMPLETE, 'Complete'),
(STATE_RETURNED, 'Returned'),
(STATE_ABORTED, 'Aborted'),
(STATE_HISTORY, 'History'),
)
# Идентификатор документа
item = models.ForeignKey('WorkItem', on_delete=models.CASCADE, related_name='jobs')
# Состояние:
state = models.IntegerField(default=STATE_IN_PROGRESS, choices=STATE_CHOICES)
class WorkItem(ModelDiffMixin, models.Model):
# Идентификатор пакета, в который входит данный документ
package = models.ForeignKey('DocumentPackage', related_name='work_items', on_delete=models.CASCADE)
class DocumentPackage(models.Model):
# Наименование пакета
name = models.TextField(null=True, blank=True, default='')