|
| 1 | +from collections import OrderedDict |
1 | 2 | from itertools import chain |
2 | 3 | from typing import Dict, Iterable, List, Optional, Tuple, Union |
3 | 4 |
|
@@ -32,22 +33,19 @@ def annotate(self, **annotations): |
32 | 33 | Normally, the annotate function doesn't allow you to use the |
33 | 34 | name of an existing field on the model as the alias name. This |
34 | 35 | version of the function does allow that. |
35 | | - """ |
36 | | - |
37 | | - fields = {field.name: field for field in self.model._meta.get_fields()} |
38 | 36 |
|
39 | | - # temporarily rename the fields that have the same |
40 | | - # name as a field name, we'll rename them back after |
41 | | - # the function in the base class ran |
42 | | - new_annotations = {} |
| 37 | + This is done by temporarily renaming the fields in order to avoid the |
| 38 | + check for conflicts that the base class does. |
| 39 | + We rename all fields instead of the ones that already exist because |
| 40 | + the annotations are stored in an OrderedDict. Renaming only the |
| 41 | + conflicts will mess up the order. |
| 42 | + """ |
| 43 | + new_annotations = OrderedDict() |
43 | 44 | renames = {} |
44 | 45 | for name, value in annotations.items(): |
45 | | - if name in fields: |
46 | | - new_name = "%s_new" % name |
47 | | - new_annotations[new_name] = value |
48 | | - renames[new_name] = name |
49 | | - else: |
50 | | - new_annotations[name] = value |
| 46 | + new_name = "%s_new" % name |
| 47 | + new_annotations[new_name] = value |
| 48 | + renames[new_name] = name |
51 | 49 |
|
52 | 50 | # run the base class's annotate function |
53 | 51 | result = super().annotate(**new_annotations) |
|
0 commit comments