(self, only_lookup_expressions: tuple[str, ...])
| 1106 | return model, table |
| 1107 | |
| 1108 | def _resolve_only(self, only_lookup_expressions: tuple[str, ...]) -> None: |
| 1109 | # Group fields by fetch fields, e.g. ["a__b", "a__c"] -> {"a": ["b", "c"]}. |
| 1110 | # The direct fields of the model are the ones that would have the key "". |
| 1111 | fetch_to_fields = defaultdict(list) |
| 1112 | # the order is important here, we need to process the shallowest fields first |
| 1113 | # because we want to populate _select_related_idx with actual items that need to be |
| 1114 | # selected, not "filler" items tha just tell the executor that an empty instance has |
| 1115 | # to be created |
| 1116 | for expression in sorted(only_lookup_expressions, key=lambda x: x.count("__")): |
| 1117 | fetch_fields_lookup, __, field_name = expression.rpartition("__") |
| 1118 | fetch_to_fields[fetch_fields_lookup].append(field_name) |
| 1119 | |
| 1120 | # select direct model fields which would have the key "": {"": ["a", "b"]} |
| 1121 | data_fields = fetch_to_fields.pop("", None) |
| 1122 | if data_fields: |
| 1123 | table = self.model._meta.basetable |
| 1124 | self._select_related_idx.append( |
| 1125 | ( |
| 1126 | self.model, |
| 1127 | len(data_fields), |
| 1128 | table, |
| 1129 | self.model, |
| 1130 | (None,), |
| 1131 | ) |
| 1132 | ) |
| 1133 | try: |
| 1134 | self.query = self.query.select( |
| 1135 | *[ |
| 1136 | table[self.model._meta.fields_db_projection[field]].as_(field) |
| 1137 | for field in data_fields |
| 1138 | if field not in self._annotations |
| 1139 | ] |
| 1140 | ) |
| 1141 | except KeyError as e: |
| 1142 | raise FieldError( |
| 1143 | f'Unknown field "{e.args[0]}" for model "{self.model.__name__}"' |
| 1144 | ) from e |
| 1145 | |
| 1146 | else: |
| 1147 | # even though no data fields are selected, we need to let the executor know |
| 1148 | # that an empty instance of the model has to be created |
| 1149 | self._select_related_idx.append( |
| 1150 | ( |
| 1151 | self.model, |
| 1152 | 0, |
| 1153 | self.model._meta.basetable, |
| 1154 | self.model, |
| 1155 | (None,), |
| 1156 | ) |
| 1157 | ) |
| 1158 | |
| 1159 | # Select fields of related models, e.g. {"a": ["b", "c"]} |
| 1160 | added_paths = set() |
| 1161 | for fetch_fields_lookup, data_fields in fetch_to_fields.items(): |
| 1162 | fetch_fields = expand_lookup_expression(self.model, fetch_fields_lookup) |
| 1163 | referring_model = model = self.model |
| 1164 | table = self.model._meta.basetable |
| 1165 | path: tuple[str | None, ...] = (None,) |
no test coverage detected