Django admin get_form无法获取动态表单字段的解决方案咨询
核心原因
get_form 方法返回的是未实例化的表单类,方法内访问的form.base_fields属于类层级的字段属性。而写在表单__init__方法中的动态字段逻辑,只有表单被实例化时才会执行,新增字段是绑定在表单实例上的。get_form执行阶段表单还未完成实例化,__init__逻辑尚未触发,自然无法读取到动态添加的字段。
示例代码存在两个会直接触发报错的问题:
get_form方法签名未定义obj参数,方法内调用super().get_form(request, obj, **kwargs)时会触发NameError- Django表单的文本域控件正确引用为
forms.Textarea,代码中写的forms.TextArea存在大小写错误,会抛出属性不存在异常
实现方案
根据实际场景选择对应实现即可:
- 如果不需要把动态字段逻辑强绑定在表单类中,可以直接把字段新增逻辑移到
get_form方法内,修改表单类的base_fields属性,后续表单实例化时会自动携带这些字段:
# admin.py from django.contrib import admin from django import forms from .models import Account class AccountAdmin(admin.ModelAdmin): def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) form.base_fields['some_field'] = forms.CharField(widget=forms.Textarea) print(form.base_fields) # 此处可读取到包含新增字段在内的所有表单字段 return form
- 如果必须保留表单
__init__内动态新增字段的逻辑,要获取实例化完成、所有字段加载完毕的表单对象,不要在get_form阶段做读取操作,可在save_form、changeform_view这类能接收到已实例化表单对象的方法中处理:
# admin.py from django.contrib import admin from .forms import MyForm class AccountAdmin(admin.ModelAdmin): form = MyForm def save_form(self, request, form, change): # 入参form为已完成实例化的表单对象,可直接读取到__init__中新增的动态字段 print(form.fields) # 此处可正常获取到some_field字段 return super().save_form(request, form, change)
如果需要在表单渲染前调整实例化后的字段属性,直接在表单__init__方法内完成对应操作即可,不需要绕到admin侧处理。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

