@@ -26,7 +26,42 @@ def __init__(self, model=None, query=None, using=None, hints=None):
2626 self .conflict_target = None
2727 self .conflict_action = None
2828
29- def rename_annotations (self , ** annotations ) -> None :
29+ def annotate (self , ** annotations ):
30+ """Custom version of the standard annotate function
31+ that allows using field names as annotated fields.
32+
33+ Normally, the annotate function doesn't allow you
34+ to use the name of an existing field on the model
35+ as the alias name. This version of the function does
36+ allow that.
37+ """
38+
39+ fields = {
40+ field .name : field
41+ for field in self .model ._meta .get_fields ()
42+ }
43+
44+ # temporarily rename the fields that have the same
45+ # name as a field name, we'll rename them back after
46+ # the function in the base class ran
47+ new_annotations = {}
48+ renames = {}
49+ for name , value in annotations .items ():
50+ if name in fields :
51+ new_name = '%s_new' % name
52+ new_annotations [new_name ] = value
53+ renames [new_name ] = name
54+ else :
55+ new_annotations [name ] = value
56+
57+ # run the base class's annotate function
58+ result = super ().annotate (** new_annotations )
59+
60+ # rename the annotations back to as specified
61+ result .rename_annotations (** renames )
62+ return result
63+
64+ def rename_annotations (self , ** annotations ):
3065 """Renames the aliases for the specified annotations:
3166
3267 .annotate(myfield=F('somestuf__myfield'))
0 commit comments