Using django with a MySQL DB and given these models:
ModelB ---FK---> ModelA
- ref_type
- ref_id
ModelC
I want to get all the ModelC for each ModelA via an annotation.
I tried many options looking at existing solutions but could not make it work.
The following code works when there is just one ModelC for each ModelA but as soon as there is more than one, I get the Subquery returns more than 1 row error and I don't know how to get a list of the ModelC models instead. Ideally, I'd like to build a list of JSON objects of the ModelC.
qs = ModelA.objects.all()
c_ids = (
ModelB.objects \
.filter(modela_id=OuterRef(OuterRef('id')), ref_type='c') \
.values('ref_id')
)
all_c = (
ModelC.objects \
.filter(id__in=Subquery(c_ids)) \
.values('id')
)
qs1 = qs.annotate(all_c=Subquery(all_c ))
for p in qs1:
print(p, p.all_c)
The following should do
which translates to
But it would be much easier if you provided your exact model definition as it's likely only a matter of doing something along the lines of (
JSONArrayAgg.filtercannot be used due to a MySQL bug.which translate to
You could also use
FilteredRelationif you want the condition to be pushed to theJOINinstead.Which results in
But the
LEFT OUTER JOINmight re-surface the issue you have with MySQL's handling ofNULLinJSON_ARRAYAGG.