Possible Bug: .values("pk") and .values("id") generate different SQL since 5.2

I encountered a bug in combination with the django_cte package but I’m not entirely sure if it’s only a django_cte bug and if the behaviour is really intended in Django 5.2.

Since Django 5.2, querying the primary keys using .values("id") or .values("pk") does not produce the same SQL anymore, since the queried values are aliased as “id” or “pk”.

Before 5.2:

In [1]: str(Location.objects.values("pk").query)
Out[1]: 'SELECT "location"."id" FROM "location"'

In [2]: str(Location.objects.values("id").query)
Out[2]: 'SELECT "location"."id" FROM "location"'

Since 5.2:

In [1]: str(Location.objects.values("pk").query)
Out[1]: 'SELECT "location"."id" AS "pk" FROM "location"'

In [2]: str(Location.objects.values("id").query)
Out[2]: 'SELECT "location"."id" AS "id" FROM "location"'

It seems like a quite fundamental difference, but I cannot produce a failing query using Django Querysets only.

django_cte stumbles here because they have indirectly hardcoded to replace .pk with .id at some point when constructing joints. Thereby it can happen that in a resulting SQL a join on id fails because the id field is aliased as pk.

See this topic just below yours called Selecting primary key in 5.2 and respective django-cte PR thanks to @simwr872.

Oh thanks, haven’t found that topic using the search. Thanks!