2009-02-09 16 views
6

Próbuję dodać pola niestandardowe do formularza InlineFormset za pomocą następującego kodu, ale pola nie będą wyświetlane w administratorze Django. Czy formularz InlineFormset jest zbyt zablokowany, aby na to zezwolić? Mój test "ding" testuje się zgodnie z oczekiwaniami, mogę wydrukować pola formularzy i zobaczyć je wszystkie, ale rzeczywiste pola nie są nigdy wyświetlane w administracji.Jak dodać niestandardowe pola do InlineFormsets?

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) 

Odpowiedz

1
model = models.Progress 

w admin nie będzie tylko pola zdefiniowane w niniejszym Progress modelu. Nie masz żadnych opcji pól/zestawów pól, które nadpisują.

Jeśli chcesz dodać nowe, istnieją dwie możliwości:

  • W definicji modelu, dodać te nowe dodatkowe pola (! Uczynić je opcjonalnie)
  • w modelu administratora (admin.TabularInline), coś dodać coś takiego:

    pola = ('newfield1', 'newfield2', '') newfield3

Spójrz na fields, fieldsets.

+0

Nie to miałem nadzieję usłyszeć, ale cóż. Przynajmniej to potwierdzone. – Soviut

4

Zrobiłem to w inny sposób:

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 

Działa to tak daleko, tylko trzeba przesłonić jakoś zapisać metodę do obsługi tego nowego pola. Zobacz: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#form. Mówi, że domyślnie Inlines używa BaseModelForm, który jest wysyłany do formset_factory. To nie działa dla mnie, próbował podklasę BaseModelForm z błędami (brak atrybutu "_meta"). Dlatego używam ModelForm.

+0

Dziękuję za tę odpowiedź. Czy masz więcej informacji na temat tego, co zrobiłeś, aby zastąpić zapisanie dla zestawu Inline? –

+0

Nie, nie pracowałem nad tym przez lata ... – alekwisnia

+2

Chcesz wspomnieć, że część 'label =' jest bardzo ważna. Bez niego jest błąd 'AttributeError: Nie można wyszukać 'my_new_field'' – TitanFighter

2

można to zrobić inną drogą (formularze dynamiczne):

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) 
+0

Dobry przykład, ale nie działa w 1.10.2. Z przykładu @ alekwisnia znalazłem, że bez 'label =' new_field nie działa. Jak \ gdzie dodać "etykietę" w twoim przykładzie? Dzięki. – TitanFighter

Powiązane problemy