Я работаю над проектом Django, в котором у меня есть набор запросов объектов 'A' (A.objects.all()
), и мне нужно аннотировать несколько полей из подзапроса объектов 'B'. Проблема в том, что метод annotate может иметь дело только с одним типом поля на параметр (DecimalField, CharField и т. Д. c.), Поэтому для аннотирования нескольких полей я должен использовать что-то вроде:
A.objects.all().annotate(b_id =Subquery(B_queryset.values('id')[:1],
b_name =Subquery(B_queryset.values('name')[:1],
b_other_field =Subquery(B_queryset.values('other_field')[:1],
... )
Что очень неэффективно, так как создает новый подзапрос / подвыбор в окончательном SQL для каждого поля, которое я хочу аннотировать. Я хотел бы использовать один и тот же Subselect с несколькими полями в его значениях values () и аннотировать их все в наборе запросов А. Я хотел бы использовать что-то вроде этого:
b_subquery = Subquery(B_queryset.values('id', 'name', 'other_field', ...)[:1])
A.objects.all().annotate(b=b_subquery)
Но когда я пытаюсь сделать это (и получить доступ к первому элементу A.objects.all().annotate(b=b_subquery)[0]
), возникает исключение:
{FieldError}Expression contains mixed types. You must set output_field.
И если я установлю Subquery(B_quer...[:1], output_field=ForeignKey(B, models.DO_NOTHING))
, я получу исключение БД:
{ProgrammingError}subquery must return only one column
В двух словах, вся проблема в том, что у меня есть несколько B, которые " принадлежит "к A, поэтому мне нужно использовать подзапрос, чтобы для каждого A в A.objects.all()
, выбрать конкретный c B и прикрепить его к этому A, используя OuterRefs и несколько фильтров (я хочу только несколько полей Б), который видит для меня тривиальную проблему.
Спасибо за любую помощь заранее!