从Django JSONField取值报错:'Api'对象无openapi_spec__info__title属性
问题解答:Django JSONField取值错误
你提到的双下划线__确实是Django中查询JSONField时的语法,但它不能直接用来访问模型实例的属性——因为openapi_spec在模型实例里是一个标准的Python字典,得用字典的键访问方式来取值。
错误原因
当你写self.openapi_spec__info__title时,Python会把它当成Api模型的一个直接属性,而这个属性根本不存在,所以才会抛出'Api' object has no attribute 'openapi_spec__info__title'的错误。双下划线语法只适用于Django ORM的QuerySet过滤场景,不能直接用于实例属性的访问。
正确的取值方式
修改你的_get_product_name方法,使用字典的索引或get方法来读取JSONField里的嵌套值:
class Api(models.Model): ''' Model to hold information on the API ''' # JSONB field to hold the OpenAPI spec openapi_spec = JSONField() # Derive product name from the OpenAPI spec, since it's a mandatory field def _get_product_name(self): # 方式1:直接索引(适用于确定info和title一定存在的场景) return self.openapi_spec['info']['title'] # 方式2:用get方法避免KeyError(推荐,防止数据缺失导致报错) # return self.openapi_spec.get('info', {}).get('title', 'Unnamed API') product_name = property(_get_product_name)
补充说明
- 如果你的OpenAPI spec数据可能存在缺失的键(比如
info或title字段不存在),推荐使用get方法:self.openapi_spec.get('info', {}).get('title', '默认值'),这样即使某个键不存在,也不会抛出KeyError,而是返回你指定的默认值。 - 双下划线的正确使用场景:在QuerySet中过滤数据时,比如要查询所有title为"Test API"的Api实例,可以这样写:
这时候Django ORM会自动将双下划线解析为JSON路径查询。Api.objects.filter(openapi_spec__info__title="Test API")
内容的提问来源于stack exchange,提问作者redmamoth
相关产品推荐
相关产品推荐

