Подсчитывать различные значения подзапроса

У меня есть эти модели:

class Component(models.Model)
    name = models.CharField(max_length=50)

class ComponentAttribute(models.Model)
    component   = models.ForeignKey(Component)
    context     = models.ForeignKey(Context)
    subcategory = models.ForeignKey(SubCategory)
    material    = models.ForeignKey(Material)
    measurement = models.ForeignKey(Measurement)
    value       = models.FloatField()

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

Основываясь на других публикациях здесь и документации по Django, я создал запрос на основе подзапроса.

# Create a subquery that counts the distinct combinations
float_attributes_count = Subquery(
        ComponentAttributeFloat.objects
        .filter(component=OuterRef('pk'))
        .order_by(
            'subcategory_id',
            'context_id',
            'material_id')
        .distinct(
            'subcategory_id',
            'context_id',
            'material_id')
        .values("component__id")
        .annotate(count=Count('id'))
        .values('count'))

components = Component.objects.annotate(
    unique_attributes=float_attributes_count
)

Когда я сейчас попытаюсь сопоставить этот запрос с этим базовым циклом, чтобы вывести свой результат.

for component in components:
    print(f'{component}: {component.unique_attributes}')

Я получаю сообщение об ошибке:

NotImplementedError: annotate() + distinct(fields) is not implemented.

Похоже, что комбинация требований, которые у меня есть, приводит к невыполнимому запросу, и я не могу найти примеры, в которых были бы установлены все флажки для меня. Кто-нибудь может помочь мне с рабочим запросом, используя другой путь? (Для справки я использую базу данных PostgreSQL, которая должна поддерживать это отдельное утверждение, см.: https://docs.djangoproject.com/en/5.2/ref/models/querysets/#django.db.models.запрос.Набор запросов.distinct)

Возможно, вы можете подсчитать комбинации значений, например:

from django.db.models import CharField, Value
from django.db.models.functions import Cast, Concat

sep = Value(',')

float_attributes_count = Subquery(
    ComponentAttributeFloat.objects.filter(component=OuterRef('pk'))
    .annotate(
        count=Count(
            Concat(
                Cast('subcategory_id', output_field=CharField()),
                sep,
                Cast('context_id', output_field=CharField()),
                sep,
                Cast('material_id', output_field=CharField()),
            ),
            distinct=True,
        )
    )
    .values('count')
)

components = Component.objects.annotate(unique_attributes=float_attributes_count)
Вернуться на верх