Django 1.7,动态管理表单

时间:2014-11-11 10:34:18

标签: python django django-forms django-admin

我试图在django admin中创建完全动态的表单。找到像thisthis这样的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字段,但不知道在哪里。

2 个答案:

答案 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。