Django重写save()方法时能否遍历模型字段动态赋值?
问题原因
你写的self.field_name = results_dict[field_name]属于硬编码属性赋值,Python不会把循环变量field_name解析成它存储的字符串值,整个循环执行过程中,你一直在给实例上名为field_name的固定临时属性赋值,根本没有触达和字典键对应的实际模型字段,值自然存不进去。
关于setattr的使用结论
这个场景下必须使用setattr完成动态赋值,这是Python原生支持的、通过字符串属性名给实例设置属性的标准方法,没有其他绕弯的必要。
正确实现方式
你原来的代码还漏了调用父类save方法的逻辑,就算赋值写对了,也不会触发实际的数据库写入,完整正确代码如下:
def save(self, *args, **kwargs): if self.text != "": results_dict = analyze(self.text) for field_name in field_names_list: # setattr参数依次为:目标实例、属性名字符串、要设置的值 setattr(self, field_name, results_dict[field_name]) # 调用父类原生save方法,完成数据库持久化 super().save(*args, **kwargs)
补充注意事项
- 确保
field_names_list里的所有字段名和模型定义的字段名完全匹配,避免拼写错误导致赋值到无关属性上 - 不要把
auto_now、auto_now_add这类框架自动维护的字段放进循环赋值列表,避免覆盖自动生成的时间值 - 如果不需要每次保存都重新生成字段值,可以加判断逻辑,仅当
self.text字段发生变更时才执行analyze和赋值操作,减少不必要的性能开销。
内容的提问来源于stack exchange,提问作者LarsLill
相关产品推荐
相关产品推荐

