Django Form的__init__方法设置的选项未传递给自定义Widget问题
问题原因及解决办法
原因分析
Django表单的初始化流程是:先创建所有Field实例(同时完成对应Widget的初始化),再执行Form的__init__方法。你在Form的__init__中给photo字段设置choices时,仅更新了Field自身的选项集合,但Widget实例早已初始化完成,它内部的choices并没有同步更新。
模板渲染时通常直接读取Field的choices生成下拉选项,所以显示正常;但表单验证阶段,Django会使用Widget的choices来校验选中值的合法性,此时Widget的choices还是初始化时的空元组,就会触发“选中值不在可用选项中”的错误。
解决办法
在Form的__init__方法中,设置完Field的choices后,同步更新对应Widget的choices即可:
修改后的Form代码:
def __init__(self, user, instance=None, *args, **kwargs): super(ProductColorVariationsForm, self).__init__(*args, **kwargs) self.fields["photo"].required = False # 用列表推导式更简洁高效 files = [(file.id, file.file.url) for file in instance.files.all()] self.fields['photo'].choices = files # 同步更新Widget的choices self.fields['photo'].widget.choices = self.fields['photo'].choices
补充说明
你可以优化files的生成方式,用列表推导式替代循环拼接元组,代码更简洁且性能更好。
内容的提问来源于stack exchange,提问作者Kjobber
相关产品推荐
相关产品推荐

