| 129 | self.name = name |
| 130 | |
| 131 | def resolve(self, resolve_context: ResolveContext) -> ResolveResult: |
| 132 | term: Term |
| 133 | joins: list[TableCriterionTuple] = [] |
| 134 | output_field = None |
| 135 | |
| 136 | main_name_part, __, rest_name_parts = self.name.partition("__") |
| 137 | if main_name_part in resolve_context.model._meta.fetch_fields: |
| 138 | # field in the format of "related_field__field" or "related_field__another_rel_field__field" |
| 139 | term, joins, output_field = resolve_nested_field( |
| 140 | resolve_context.model, resolve_context.table, self.name |
| 141 | ) |
| 142 | elif ( |
| 143 | rest_name_parts |
| 144 | and main_name_part in resolve_context.model._meta.fields_map |
| 145 | and isinstance(resolve_context.model._meta.fields_map[main_name_part], JSONField) |
| 146 | ): |
| 147 | # Accessing a JSON field, e.g. F("json_field__a__b") |
| 148 | key_parts = [ |
| 149 | int(item) if item.isdigit() else str(item) for item in rest_name_parts.split("__") |
| 150 | ] |
| 151 | term = resolve_field_json_path( |
| 152 | PypikaField(resolve_context.model._meta.fields_db_projection[main_name_part]), |
| 153 | key_parts, |
| 154 | ) |
| 155 | elif self.name in resolve_context.annotations: |
| 156 | # reference to another annotation, e.g. M.annotate(f1=...).annotate(f2=F("f1")).values('field') |
| 157 | annotation = resolve_context.annotations[self.name] |
| 158 | if isinstance(annotation, Term): |
| 159 | term = annotation |
| 160 | else: |
| 161 | term = annotation.resolve(resolve_context).term |
| 162 | else: |
| 163 | # a regular model field, e.g. F("id") |
| 164 | try: |
| 165 | meta = resolve_context.model._meta |
| 166 | term = PypikaField(meta.fields_db_projection[self.name]) |
| 167 | |
| 168 | if (output_field := meta.fields_map.get(self.name, None)) and ( |
| 169 | func := output_field.get_for_dialect( |
| 170 | meta.db.capabilities.dialect, "function_cast" |
| 171 | ) |
| 172 | ): |
| 173 | term = func(output_field, term) |
| 174 | except KeyError: |
| 175 | raise FieldError( |
| 176 | f"There is no non-virtual field {self.name} on Model {resolve_context.model.__name__}" |
| 177 | ) from None |
| 178 | return ResolveResult(term=term, output_field=output_field, joins=joins) |
| 179 | |
| 180 | def _combine(self, other: Any, connector: Connector, right_hand: bool) -> CombinedExpression: |
| 181 | if not isinstance(other, Expression): |