@@ -397,18 +397,12 @@ def build_query(self, columns=None):
397397 def columns (self ):
398398 """
399399 Return a tuple of (name, expression) with the columns and annotations
400- which should be loaded by the query.
400+ which should be loaded by the query
401401 """
402402 select_mask = self .query .get_select_mask ()
403403 columns = (
404404 self .get_default_columns (select_mask ) if self .query .default_cols else self .query .select
405405 )
406- # Populate QuerySet.select_related() data.
407- related_columns = []
408- if self .query .select_related :
409- self .get_related_selections (related_columns , select_mask )
410- if related_columns :
411- related_columns , _ = zip (* related_columns , strict = True )
412406
413407 annotation_idx = 1
414408
@@ -427,11 +421,30 @@ def project_field(column):
427421 annotation_idx += 1
428422 return target , column
429423
430- return (
431- tuple (map (project_field , columns ))
432- + tuple (self .annotations .items ())
433- + tuple (map (project_field , related_columns ))
434- )
424+ selected = []
425+ if self .query .selected is None :
426+ selected = [
427+ * (project_field (col ) for col in columns ),
428+ * self .annotations .items (),
429+ ]
430+ else :
431+ for expression in self .query .selected .values ():
432+ # Reference to an annotation.
433+ if isinstance (expression , str ):
434+ alias , expression = expression , self .annotations [expression ]
435+ # Reference to a column.
436+ elif isinstance (expression , int ):
437+ alias , expression = project_field (columns [expression ])
438+ selected .append ((alias , expression ))
439+
440+ # Populate QuerySet.select_related() data.
441+ related_columns = []
442+ if self .query .select_related :
443+ self .get_related_selections (related_columns , select_mask )
444+ if related_columns :
445+ related_columns , _ = zip (* related_columns , strict = True )
446+
447+ return tuple (selected ) + tuple (map (project_field , related_columns ))
435448
436449 @cached_property
437450 def base_table (self ):
@@ -478,7 +491,11 @@ def get_combinator_queries(self):
478491 # If the columns list is limited, then all combined queries
479492 # must have the same columns list. Set the selects defined on
480493 # the query on all combined queries, if not already set.
481- if not compiler_ .query .values_select and self .query .values_select :
494+ selected = self .query .selected
495+ if selected is not None and compiler_ .query .selected is None :
496+ compiler_ .query = compiler_ .query .clone ()
497+ compiler_ .query .set_values (selected )
498+ elif not compiler_ .query .values_select and self .query .values_select :
482499 compiler_ .query = compiler_ .query .clone ()
483500 compiler_ .query .set_values (
484501 (
0 commit comments