自定义Django CardiosField迁移报错:get_prep_value需处理None值吗?
解答你的Django自定义字段Migrate报错问题
嘿,这个问题我之前做自定义字段的时候也踩过坑,来给你拆解清楚:
问题根源
你在Workout模型里给自定义的CardiosField设了null=True,意味着这个字段允许存储空值(数据库层面的NULL)。当Django执行迁移或者处理空值时,会调用字段的get_prep_value方法来准备要存入数据库的值。但你的get_prep_value方法里没有处理value为None的情况,直接去访问value.series——None当然没有series属性,所以就触发了AttributeError。
是否必须处理None值?
是的,必须处理。只要你的字段允许null=True,get_prep_value就必须能兼容None的场景。Django内置的JSONField其实已经做了这个处理:当传入的值是None时,它会直接返回None,不会执行后续的序列化逻辑。而你重写这个方法后,覆盖了原有处理None的逻辑,才导致了报错。
修复方案
给你的get_prep_value方法加上None判断就可以了,比如:
from django.contrib.postgres.fields import JSONField class CardiosField(JSONField): def get_prep_value(self, value): # 先处理None的情况 if value is None: return None # 再执行你的自定义逻辑 processed_data = value.series # 这里是你的原有处理逻辑 return super().get_prep_value(processed_data)
这样当字段值为None时,直接返回None,Django就会把它转换成数据库的NULL值,不会触发属性访问错误。
另外补充个小提醒:如果你的CardiosField是用来序列化自定义对象的,一定要确保在访问对象属性前,先确认对象不是None,这是自定义字段处理空值的基本要求哦。
内容的提问来源于stack exchange,提问作者Sahand




