Django动态调用序列化器报错:'str'对象无指定属性,求排查
动态调用Django序列化器引发AttributeError问题
错误信息
'str' object has no attribute '<module 'django.db.models' from 'C:\Python310\lib\site-packages\django\db\models\__init__.py'>'
问题场景
尝试通过Python的getattr()函数,结合序列化器名称与模型查询集动态访问序列化器,配合动态URL实现接口,但运行后触发上述错误,无法正常返回序列化数据。
原有代码
@api_view(['GET']) def List_all_part(request, part): table = apps.get_model('Parts', part) model = table.objects.all() serializer = getattr(str(part.lower()), str(models)) return Response(serializer.data)
错误原因分析
getattr()参数完全误用:getattr()的第一个参数必须是对象/模块,第二个参数是该对象/模块下的属性名称(字符串)。你把字符串str(part.lower())作为第一个参数,把模块models转成字符串作为第二个参数,完全违背函数用法,这才触发了"字符串对象不存在某模块属性"的错误。- 序列化器调用逻辑错误:序列化器需要先实例化并传入查询集作为参数,你直接通过
getattr获取后就调用.data属性,完全跳过了实例化步骤。 - 序列化器动态获取路径错误:你错误地试图通过模型名称直接获取序列化器,正确的做法是从序列化器所在的模块中,根据类名动态获取。
解决方案
假设你的序列化器都定义在Parts.serializers模块中,且序列化器类名遵循[模型名]Serializer的命名规则(例如模型为Gear,序列化器为GearSerializer),可按以下方式修改代码:
from django.apps import apps from rest_framework.decorators import api_view from rest_framework.response import Response # 导入序列化器所在模块 from Parts import serializers @api_view(['GET']) def List_all_part(request, part): # 获取目标模型类 table = apps.get_model('Parts', part) # 获取模型查询集 queryset = table.objects.all() # 拼接对应序列化器类名 serializer_class_name = f"{part.capitalize()}Serializer" # 从serializers模块中动态获取序列化器类 serializer_class = getattr(serializers, serializer_class_name) # 实例化序列化器(many=True表示处理多条数据) serializer = serializer_class(queryset, many=True) # 返回序列化后的数据 return Response(serializer.data)
注意事项
- 确保序列化器类名与模型名的对应规则一致,若类名规则不同,需调整类名拼接逻辑。
- 如果序列化器分布在不同模块,需修改导入的模块路径,保证
getattr能正确定位到目标类。 - 建议添加异常处理(如捕获
AttributeError),当找不到对应序列化器时返回明确的错误响应,避免直接抛出异常。
内容的提问来源于stack exchange,提问作者Emad G
相关产品推荐
相关产品推荐

