2009-02-09 18 views
6

Estoy tratando de agregar campos personalizados a un InlineFormset usando el siguiente código, pero los campos no se mostrarán en el administrador de Django. ¿El InlineFormset está demasiado bloqueado para permitir esto? Mi prueba de impresión "ding" se dispara como se esperaba, puedo imprimir los campos de formulario y verlos allí, pero los campos reales nunca se representan en el administrador.Cómo agregar campos personalizados a 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) 

Respuesta

1
model = models.Progress 

En el administrador habrá sólo los campos definidos en este modelo Progreso. No tiene opción de campos/conjuntos de campos que la sobrescriban.

Si desea agregar los nuevos, hay dos opciones:

  • En la definición del modelo, añadir esos nuevos campos adicionales (! Hacerlos opcional)
  • En el modelo de administración (admin.TabularInline), añadir algo algo como:

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

Eche un vistazo a fields, fieldsets.

+0

No es lo que esperaba oír, pero bueno. Al menos está confirmado. – Soviut

4

lo hice de otra manera:

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 

Esto funciona hasta el momento, sólo tengo que anular alguna manera el método save para manejar este nuevo campo. Vea esto: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#form. Dice que, por defecto, Inlines usa BaseModelForm, que se envía a formset_factory. No funciona para mí, intenté subclasificar BaseModelForm con errores (sin atributo '_meta'). Entonces uso ModelForm en su lugar.

+0

Gracias por esta respuesta. ¿Tiene más información sobre lo que hizo para anular guardar para el Inline Formset? –

+0

No, no he trabajado en esto por años ... – alekwisnia

+2

Quiero mencionar que la parte 'label =' es muy importante. Sin él, existe el error 'AttributeError: no se puede buscar 'my_new_field'' – TitanFighter

2

Puede hacerlo por otro camino (formularios dinámicos):

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

Buen ejemplo, pero no funciona en 1.10.2. Del ejemplo de @ alekwisnia que encontré, que sin 'label =' new_field no funciona. ¿Cómo \ donde agregar la 'etiqueta' en tu ejemplo? Gracias. – TitanFighter

Cuestiones relacionadas