@@ -26,7 +26,42 @@ def __init__(self, model=None, query=None, using=None, hints=None):
26
26
self .conflict_target = None
27
27
self .conflict_action = None
28
28
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 ):
30
65
"""Renames the aliases for the specified annotations:
31
66
32
67
.annotate(myfield=F('somestuf__myfield'))
0 commit comments