Найти - Пользователи
Полная версия: Django 1.7, динамическая форма в админке
Начало » Django » Django 1.7, динамическая форма в админке
1
sptica
Всем привет!

Мне нужно, в зависимости от начального значения одного из полей формы админки, создавать нужное количество доп полей, заполнив их значениями из БД. По запросу создания динамических полей админки джанго гугл выдал несколько вариантов решения, например вот этот и ещё вот этот. Суть у них одна и та-же - переопределить метод get_fieldsets класса admin.ModelAdmin.

У меня не сработало. Вот на такой код:
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")

Я получаю ошибку “Unknown field(s) (item_type) specified for Device. Check fields/fieldsets/exclude attributes of class DeviceAdmin”. И дальше не знаю в какую сторону рыть. По этой ошибке гугл ничего внятного не выдаёт и, насколько я понял, где-то нужно дополнительно определить это новое поле. Я пробовал ставить точку останова в начале конструктора класса MyDeviceAdminForm чтобы посмотреть значения полей, но джанго выдаёт ошибку раньше и эта точка останова не срабатывает.

Моих знаний здесь явно не достаточно, уже дошёл до мысли переписать эту часть админки, но как то этот вариант похож на изобретение велосипеда и не очень радует. Товарищи, кто знает джанго глубже, помогите пожалуйста, буду очень признателен!
GreyZmeem
Метод get_fieldsets вызывается в методе get_form
https://github.com/django/django/blob/1.7.1/django/contrib/admin/options.py#L643
После чего список fields (и все остальное) передается в modelform_factory, которая создает форму на основе этих данных. В процессе создания проверяется чтобы все поля присутсвывали в моделе: https://github.com/django/django/blob/1.7.1/django/forms/models.py#L241

В принцыпе, достаточно сделать что-то вроде:
class MyTestModelAdminForm(ModelForm):
    test_field_not_present_in_model = CharField(254)
 
class MyTestModelAdmin(admin.ModelAdmin):
    list_display = ('name', )
    form = MyTestModelAdminForm
admin.site.register(MyTestModel, MyTestModelAdmin)
И у вас в админке появится этот field… Но для чего это нужно?
sptica
GreyZmeem, спасибо, но такой способ в данном случае не подходит. Я не знаю в ModelForm'е точного кол-ва и названия полей, чтобы прописывать их в виде атрибутов класса. Подошло бы определение через конструктор, но для админской формы этот способ не работает.

Исходники как раз сейчас изучаю и ищу способы решения. Спасибо!

Задача у меня вот какая. Есть устроства, типы устройств и свойства типов устройств. Т.е. у разных типов устройств разные свойства. Для компьютера это мат плата и проц, для принтера и смартфона модель и фирма производитель и так далее.

Идея в том, чтобы через админку добавлять свойства к типам устройств, а затем на странице самого устройства, выбрав тип, увидеть относящиеся к этому типу свойства.

Вот определение моделей:
class Device(models.Model):
    people = models.ManyToManyField(People, verbose_name='Владелец устройства', blank=True)
    type_of_device = models.ForeignKey(TypeOfDevice, null=True, verbose_name='Тип устройства')
class TypeOfDevice(models.Model):        
    device_type = models.CharField(max_length=40, verbose_name='Тип устройства')
    property_of = models.ManyToManyField(PropertyOfTypeOfDevice, null=True, blank=True, verbose_name='Свойства')
class PropertyOfTypeOfDevice(models.Model):
    property_name = models.CharField(max_length=30, verbose_name='Имя свойства')
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB