@@ -350,21 +350,19 @@ def build_query(self, columns=None):
350
350
self .check_query ()
351
351
query = self .query_class (self )
352
352
ordering_fields , sort_ordering , extra_fields = self ._get_ordering ()
353
- query .project_fields = self .get_project_fields (columns , ordering_fields )
354
353
query .ordering = sort_ordering
355
- # If columns is None, then get_project_fields() won't add
356
- # ordering_fields to $project. Use $addFields (extra_fields) instead.
357
- if columns is None :
358
- extra_fields += ordering_fields
359
- if extra_fields :
360
- query .extra_fields = self .get_project_fields (extra_fields , force_expression = True )
361
354
if self .query .combinator :
362
355
if not getattr (self .connection .features , f"supports_select_{ self .query .combinator } " ):
363
356
raise NotSupportedError (
364
357
f"{ self .query .combinator } is not supported on this database backend."
365
358
)
366
359
query .combinator_pipeline = self .get_combinator_queries ()
367
360
else :
361
+ query .project_fields = self .get_project_fields (columns , ordering_fields )
362
+ # If columns is None, then get_project_fields() won't add
363
+ # ordering_fields to $project. Use $addFields (extra_fields) instead.
364
+ if columns is None :
365
+ extra_fields += ordering_fields
368
366
query .lookup_pipeline = self .get_lookup_pipeline ()
369
367
where = self .get_where ()
370
368
try :
@@ -373,6 +371,8 @@ def build_query(self, columns=None):
373
371
query .mongo_query = {}
374
372
else :
375
373
query .mongo_query = {"$expr" : expr }
374
+ if extra_fields :
375
+ query .extra_fields = self .get_project_fields (extra_fields , force_expression = True )
376
376
return query
377
377
378
378
def get_columns (self ):
@@ -381,10 +381,8 @@ def get_columns(self):
381
381
which should be loaded by the query.
382
382
"""
383
383
select_mask = self .query .get_select_mask ()
384
- columns = filter (
385
- # The extra order by columns are handled by order_by_objs variables.
386
- lambda col : not isinstance (col , OrderBy ),
387
- self .get_default_columns (select_mask ) if self .query .default_cols else self .query .select ,
384
+ columns = (
385
+ self .get_default_columns (select_mask ) if self .query .default_cols else self .query .select
388
386
)
389
387
# Populate QuerySet.select_related() data.
390
388
related_columns = []
@@ -400,6 +398,9 @@ def project_field(column):
400
398
if hasattr (column , "target" ):
401
399
# column is a Col.
402
400
target = column .target .column
401
+ # Handle Order by columns as refs columns.
402
+ elif isinstance (column , OrderBy ) and isinstance (column .expression , Ref ):
403
+ target = column .expression .refs
403
404
else :
404
405
# column is a Transform in values()/values_list() that needs a
405
406
# name for $proj.
@@ -427,6 +428,8 @@ def get_combinator_queries(self):
427
428
query .get_compiler (self .using , self .connection , self .elide_empty )
428
429
for query in self .query .combined_queries
429
430
]
431
+ main_query_columns = self .get_columns ()
432
+ main_query_fields , _ = zip (* main_query_columns , strict = True )
430
433
for compiler_ in compilers :
431
434
try :
432
435
# If the columns list is limited, then all combined queries
@@ -443,8 +446,10 @@ def get_combinator_queries(self):
443
446
)
444
447
compiler_ .pre_sql_setup ()
445
448
# Standardize columns as main query required.
446
- _ , exprs = zip (* compiler_ .get_columns (), strict = True )
447
- columns = tuple (zip (self .query .values_select , exprs , strict = True ))
449
+ columns = compiler_ .get_columns ()
450
+ if self .query .values_select :
451
+ _ , exprs = zip (* columns , strict = True )
452
+ columns = tuple (zip (main_query_fields , exprs , strict = True ))
448
453
parts .append ((compiler_ .build_query (columns ), compiler_ .collection_name ))
449
454
450
455
except EmptyResultSet :
@@ -464,12 +469,14 @@ def get_combinator_queries(self):
464
469
)
465
470
if not self .query .combinator_all :
466
471
ids = {}
467
- for alias , expr in self .get_columns ():
468
- ids [alias ] = (
469
- expr .as_mql (self , self .connection )
470
- if isinstance (expr , Col | Ref )
471
- else f"${ alias } "
472
- )
472
+ for alias , expr in main_query_columns :
473
+ collection = expr .alias if isinstance (expr , Col ) else None
474
+ if collection and collection != self .collection_name :
475
+ ids [
476
+ f"{ expr .alias } { self .GROUP_SEPARATOR } { expr .target .column } "
477
+ ] = expr .as_mql (self , self .connection )
478
+ else :
479
+ ids [alias ] = f"${ alias } "
473
480
combinator_pipeline .append ({"$group" : {"_id" : ids }})
474
481
projected_fields = defaultdict (dict )
475
482
for key in ids :
0 commit comments