def resolve_lookup_into_field(self, model_cls: Type[Model], lookup: str) -> Union[Field, ForeignObjectRel]: query = Query(model_cls) lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup) if lookup_parts: raise LookupsAreUnsupported() return self._resolve_field_from_parts(field_parts, model_cls)
def resolve_lookup(self, model_cls: Type[Model], lookup: str) -> Field: query = Query(model_cls) lookup_parts, field_parts, is_expression = query.solve_lookup_type( lookup) if lookup_parts: raise FieldError('Lookups not supported yet') currently_observed_model = model_cls current_field = None for field_part in field_parts: if field_part == 'pk': return self.django_context.get_primary_key_field( currently_observed_model) current_field = currently_observed_model._meta.get_field( field_part) if not isinstance(current_field, (ForeignObjectRel, RelatedField)): continue currently_observed_model = self.django_context.fields_context.get_related_model_cls( current_field) if isinstance(current_field, ForeignObjectRel): current_field = self.django_context.get_primary_key_field( currently_observed_model) # if it is None, solve_lookup_type() will fail earlier assert current_field is not None return current_field
def resolve_lookup_expected_type(self, ctx: MethodContext, model_cls: Type[Model], lookup: str) -> MypyType: query = Query(model_cls) try: lookup_parts, field_parts, is_expression = query.solve_lookup_type( lookup) if is_expression: return AnyType(TypeOfAny.explicit) except FieldError as exc: ctx.api.fail(exc.args[0], ctx.context) return AnyType(TypeOfAny.from_error) field = self._resolve_field_from_parts(field_parts, model_cls) lookup_cls = None if lookup_parts: lookup = lookup_parts[-1] lookup_cls = field.get_lookup(lookup) if lookup_cls is None: # unknown lookup return AnyType(TypeOfAny.explicit) if lookup_cls is None or isinstance(lookup_cls, Exact): return self.get_field_lookup_exact_type( helpers.get_typechecker_api(ctx), field) assert lookup_cls is not None lookup_info = helpers.lookup_class_typeinfo( helpers.get_typechecker_api(ctx), lookup_cls) if lookup_info is None: return AnyType(TypeOfAny.explicit) for lookup_base in helpers.iter_bases(lookup_info): if lookup_base.args and isinstance(lookup_base.args[0], Instance): lookup_type: MypyType = lookup_base.args[0] # if it's Field, consider lookup_type a __get__ of current field if (isinstance(lookup_type, Instance) and lookup_type.type.fullname() == fullnames.FIELD_FULLNAME): field_info = helpers.lookup_class_typeinfo( helpers.get_typechecker_api(ctx), field.__class__) if field_info is None: return AnyType(TypeOfAny.explicit) lookup_type = helpers.get_private_descriptor_type( field_info, '_pyi_private_get_type', is_nullable=field.null) return lookup_type return AnyType(TypeOfAny.explicit)