Reputation: 5789
I'm trying to make fully dynamic form in django admin. Found solution in goole like this and this. But this solution does not 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")
Got this error: "Unknown field(s) (item_type) specified for Device. Check fields/fieldsets/exclude attributes of class DeviceAdmin."
And i can't find solution for this. I understand that i need to define in some other place foo field, but does not know where.
Upvotes: 3
Views: 656
Reputation: 367
Django > 1.4 introduced a change that causes this breakage. Basically get_fieldsets is called before the form factory, and then the factory complains about the extra field you introduce in get_fieldsets. Luckily get_fieldsets is called more than once, presenting opportunity to subvert the flow. My solution is to add a marker attribute to the request while it passes through the form mechanism:
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
Upvotes: 3
Reputation: 3308
If it is just the field name visible to the user that you want to alter (the internal field name will not be visible anyway), you could use a class factory:
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")
This works in Django 1.6.
Upvotes: 0