我试图在django admin中创建完全动态的表单。找到像this和this这样的goole解决方案。但是这个解决方案对我不起作用。例如这段代码:
class DeviceAdmin(admin.ModelAdmin):
form = MyDeviceAdminForm
def get_fieldsets(self, request, obj=None):
fieldsets = super(DeviceAdmin, self).get_fieldsets(request, obj)
fieldsets[0][1]['fields'] += ('foo',)
return fieldsets
class MyDeviceAdminForm(forms.ModelForm):
class Meta:
model = Device
def __init__(self, *args, **kwargs):
super(MyDeviceAdminForm, self).__init__(*args, **kwargs)
self.fields['foo'] = forms.IntegerField(label="foo")
出现此错误:"为设备指定的未知字段(item_type)。检查字段/字段集/排除类DeviceAdmin的属性。"
我无法找到解决方案。我明白我需要在其他地方定义foo字段,但不知道在哪里。
答案 0 :(得分:3)
Django> 1.4引入了导致这种破坏的变化。基本上get_fieldsets在表单工厂之前调用,然后工厂会抱怨你在get_fieldsets中引入的额外字段。幸运的是,get_fieldsets不止一次被调用,提供了破坏流程的机会。我的解决方案是在请求通过表单机制时为请求添加标记属性:
def get_fieldsets(self, request, obj=None):
fieldsets = super(DeviceAdmin, self).get_fieldsets(request, obj)
if hasattr(request, "_gfs_marker"):
fieldsets[0][1]['fields'] += ('foo',)
setattr(request, "_gfs_marker", 1)
return fieldsets
答案 1 :(得分:0)
如果只是您想要更改的用户可见的字段名称(内部字段名称无论如何都不可见),您可以使用类工厂:
def get_MyDeviceAdminForm(field_name):
class MyDeviceAdminForm(forms.ModelForm):
my_new_field_internal = forms.CharField(label=field_name)
class Meta:
model = InfoLog
return MyDeviceAdminForm
class DeviceAdmin(admin.ModelAdmin):
form = get_MyDeviceAdminForm("Verbose name of the new field")

这适用于Django 1.6。