Джанго 1.7, динамическая форма администратора

Обновить

December 2018

Просмотры

541 раз

3

Я пытаюсь сделать полностью динамическую форму в Джанго администратора. Найдено решение в Гуле , как это и это . Но это решение не работает для меня. Например , этот код:

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

Получил эту ошибку: «Неизвестное поле (s) (item_type), указанная для устройства Проверьте поля / fieldsets / исключить атрибуты класса DeviceAdmin.»

И я не могу найти решение для этого. Я понимаю, что мне нужно, чтобы определить, в каком-то другом поле места Foo, но не знаю, где.

2 ответы

2

Джанго> 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
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.