Dan,
The root of the issue here is that you query is asking to retrieve all fields from
the Parent table and perform an aggregation on the JOIN'ed child table.
That results in the following query
SELECT parent.*, MAX(child.updated_timestamp)
FROM parent
...
Since you SELECT all parent columns Django has no choice but to GROUP BY
parent.* as well because on Oracle GROUP BY must contain all non-aggregate
SELECT clauses. That is not the case on MySQL and PostgreSQL for example.
If you use .values('id') as you described you'll only SELECT
parent.id which will
solve your issue as you've come to discover.
FWIW .only('id') would have worked as well and returned Parent objects instead
of a dict but all fields accesses would have been deferred.
Also there's a ticket tracking support for aggregation through subquery that would
have worked for your case[0]
Parent.objects.annotate(
child_updated_timestamp=Child.objects.filter(
parent=OuterRef('pk'),
).aggregate(Max('updated_timestamp'))
)
Cheers,
Simon