Как добавить пользовательские поля в InlineFormsets?
-
22-08-2019 - |
Вопрос
Я пытаюсь добавить пользовательские поля в InlineFormset, используя следующий код, но поля не будут отображаться в Django Admin.Является ли InlineFormset слишком заблокированным, чтобы разрешить это?Мой тест печати "ding" срабатывает, как и ожидалось, я могу распечатать form.fields и увидеть их все там, но фактические поля никогда не отображаются в admin.
admin.py
from django.contrib import admin
import models
from django.forms.models import BaseInlineFormSet
from django import forms
from forms import ProgressForm
from django.template.defaultfilters import slugify
class ProgressInlineFormset(BaseInlineFormSet):
def add_fields(self, form, index):
print "ding"
super(ProgressInlineFormset, self).add_fields(form, index)
for criterion in models.Criterion.objects.all():
form.fields[slugify(criterion.name)] = forms.IntegerField(label=criterion.name)
class ProgressInline(admin.TabularInline):
model = models.Progress
extra = 8
formset = ProgressInlineFormset
class ReportAdmin(admin.ModelAdmin):
list_display = ("name", "pdf_column",)
search_fields = ["name",]
inlines = (ProgressInline,)
admin.site.register(models.Report, ReportAdmin)
Решение
model = models.Progress
В admin будут только поля, определенные в этом Прогресс Модель.У вас нет опции fields / fieldsets перезаписать его.
Если вы хотите добавить новые, есть два варианта:
- В определении модели добавьте эти новые дополнительные поля (сделайте их необязательными!).
В модели администратора (администратор.Табличная строка), добавьте что-то вроде:
поля = ('новое поле 1', 'новое поле 2', 'новое поле 3')
Взгляните на поля, наборы полей.
Другие советы
Я сделал это по-другому:
forms.py:
from django import forms
class ItemAddForm(forms.ModelForm):
my_new_field = forms.IntegerField(initial=1, label='quantity')
class Meta:
model = Item
admin.py:
from django.contrib import admin
from forms import *
class ItemAddInline(admin.TabularInline):
form = ItemAddForm
Пока это работает, мне нужно только каким-то образом переопределить метод save для обработки этого нового поля.Видишь это: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#form .В нем говорится, что по умолчанию в строках используется BaseModelForm , которая отправляется в formset_factory.У меня это не работает, пытался создать подкласс BaseModelForm с ошибками (нет атрибута '_meta').Поэтому вместо этого я использую ModelForm .
Вы можете сделать это другим способом (динамические формы):
admin.py
class ProgressInline(admin.TabularInline):
model = models.Progress
extra = 8
def get_formset(self, request, obj=None, **kwargs):
extra_fields = {'my_field': forms.CharField()}
kwargs['form'] = type('ProgressForm', (forms.ModelForm,), extra_fields)
return super(ProgressInline, self).get_formset(request, obj, **kwargs)