Django 1.7 dynamic admin form

I am trying to make a fully dynamic form in django admin. Found solution on goole like this and this . But this solution doesn't work for me. For example, this code:

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")

      

Get this error: "Unknown fields (item_type) specified for device. Check fields / fields / exclude attributes of DeviceAdmin class."

And I can't seem to find a solution for this. I understand that I need to define a field somewhere else in foo, but I don't know where.

+3


source to share


2 answers


Django> 1.4 introduced a change that triggers this gender. Basically get_fieldsets is called before the factory form and then the factory complains about the extra field you put in get_fieldsets. Fortunately, get_fieldsets is called more than once, which makes it possible to disrupt the flow. My solution is to add a marker attribute to the request as it goes through the form engine:



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

      

+2


source


If it's just a field name that is visible to the user that you want to change (the internal field name won't be visible anyway), you can use a factory class:



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")
      

Run codeHide result


This works in Django 1.6.

0


source







All Articles