@@ -128,6 +128,8 @@ def get_field_lookup_exact_type(
128128 ) -> MypyType :
129129 if isinstance (field , (RelatedField , ForeignObjectRel )):
130130 related_model_cls = self .get_field_related_model_cls (field )
131+ if related_model_cls is None :
132+ return AnyType (TypeOfAny .from_error )
131133 primary_key_field = self .get_primary_key_field (related_model_cls )
132134 primary_key_type = self .get_field_get_type (api , primary_key_field , method = "init" )
133135
@@ -353,7 +355,7 @@ def get_field_related_model_cls(
353355
354356 def _resolve_field_from_parts (
355357 self , field_parts : Iterable [str ], model_cls : Type [Model ]
356- ) -> Union ["Field[Any, Any]" , ForeignObjectRel ]:
358+ ) -> Union ["Field[Any, Any]" , ForeignObjectRel , None ]:
357359 currently_observed_model = model_cls
358360 field : Union ["Field[Any, Any]" , ForeignObjectRel , GenericForeignKey , None ] = None
359361 for field_part in field_parts :
@@ -363,13 +365,19 @@ def _resolve_field_from_parts(
363365
364366 field = currently_observed_model ._meta .get_field (field_part )
365367 if isinstance (field , RelatedField ):
366- currently_observed_model = self .get_field_related_model_cls (field )
368+ related_model = self .get_field_related_model_cls (field )
369+ if related_model is None :
370+ return None
371+ currently_observed_model = related_model
367372 model_name = currently_observed_model ._meta .model_name
368373 if model_name is not None and field_part == (model_name + "_id" ):
369374 field = self .get_primary_key_field (currently_observed_model )
370375
371376 if isinstance (field , ForeignObjectRel ):
372- currently_observed_model = self .get_field_related_model_cls (field )
377+ related_model = self .get_field_related_model_cls (field )
378+ if related_model is None :
379+ return None
380+ currently_observed_model = related_model
373381
374382 # Guaranteed by `query.solve_lookup_type` before.
375383 assert isinstance (field , (Field , ForeignObjectRel ))
@@ -397,9 +405,18 @@ def solve_lookup_type(
397405 field = query .get_meta ().get_field (query_parts [0 ])
398406 except FieldDoesNotExist :
399407 return None
408+
400409 if len (query_parts ) == 1 :
401410 return [], [query_parts [0 ]], False
402- sub_query = Query (field .related_model ).solve_lookup_type ("__" )
411+
412+ related_model = None
413+ if isinstance (field , (RelatedField , ForeignObjectRel )):
414+ related_model = self .get_field_related_model_cls (field )
415+
416+ if related_model is None :
417+ return None
418+
419+ sub_query = Query (related_model ).solve_lookup_type ("__" .join (query_parts [1 :]))
403420 entire_query_parts = [query_parts [0 ], * sub_query [1 ]]
404421 return sub_query [0 ], entire_query_parts , sub_query [2 ]
405422
@@ -428,6 +445,8 @@ def resolve_lookup_expected_type(self, ctx: MethodContext, model_cls: Type[Model
428445 return AnyType (TypeOfAny .explicit )
429446
430447 field = self ._resolve_field_from_parts (field_parts , model_cls )
448+ if field is None :
449+ return AnyType (TypeOfAny .from_error )
431450
432451 lookup_cls = None
433452 if lookup_parts :
0 commit comments