1 问题及其原因:
1.1 问题
django模型执行get_FIELD_display()时报错 TypeError: ‘str’ object is not callable
1.2 原因
是由于drf序列化器字段的source使用了get_FIELD_display同时前端传入的数据也有这个序列化器字段导致drf进行setattr修改了get_FIELD_display
修复方式:前端传参把source=get_FIELD_display的序列化器字段剔除
2 源码分析
以update操作为例
-
接口传入data数据以及执行is_valid方法
-
传入的data数据赋值给了initial_data
-
is_valid方法会调用run_validation方法,参数为第2点的initial_data(即request.data)
-
run_validation方法会执行to_internal_value方法将data的数据提取出来并返回
5.to_internal_value方法执行get_value方法,self.field_name为当前序列化字段的名字,相当于直接在request.data中拿到了当前序列化字段数据
-
to_internal_value方法执行set_value方法,第二个参数使用了当前序列化字段的source处理后的值(source=‘get_FIELD_display’可以视为直接拿’get_FIELD_display’)
-
set_value方法直接拿第二个参数的最后一个作为key保存值
-
当is_valid执行完成后,_validated_data的数据已经更新(存在了key为get_FIELD_display的数据),此时执行perform_update
-
直接将_validated_data作为update的第二个参数
-
update进行了setattr,将原来的get_FIELD_display方法变成了一个属性(value是具体的值),因此出现以上问题