I'm using StringAgg and order as follows:
# Get order column & annotate with list of credits
if request.POST.get('order[0][name]'):
order = request.POST['order[0][name]']
if order == 'credits_primary':
releases = releases.annotate(credits_primary=StringAgg(
'credits__entity__name',
delimiter=', ',
filter=Q(credits__type='primary'),
ordering='credits__id'
))
elif order == 'credits_secondary':
releases = releases.annotate(credits_secondary=StringAgg(
'credits__entity__name',
delimiter=', ',
filter=Q(credits__type='secondary'),
ordering='credits__id'
))
else:
order = 'title'
# Order releases
if request.POST.get('order[0][dir]') == 'desc':
releases = releases.order_by(F(order).desc(nulls_last=True), 'title')
else:
releases = releases.order_by(F(order).asc(nulls_last=True), 'title')
for release in releases:
try: print(release.credits_primary)
except: pass
try: print(release.credits_secondary)
except: pass
This in itself works exactly as expected: the ordering is what I expect, and print returns the values I expect.
However, when I apply a filter before this, where the result includes multiple instances of the same release, the credits__entity__names will be repeated or omitted for that release, depending on how many results there are for the field(s) being filtered by, despite using distinct.
Below is the filter I'm applying that affects the aggregation (applied before StringAgg):
# Other filters...
# Filter by Search
if request.POST.get('search[value]'):
query = Q()
search = request.POST['search[value]']
query.add(Q(title__icontains=search), Q.OR)
query.add(Q(tags__tag__name__icontains=search), Q.OR)
query.add(Q(credits__entity__name__icontains=search), Q.OR)
releases = releases.filter(query)
# Make sure items aren't repeated
releases = releases.distinct()