2009-02-09 7 views
6

J'essaie d'ajouter des champs personnalisés à un InlineFormset en utilisant le code suivant, mais les champs n'apparaîtront pas dans l'Admin Django. Est-ce que InlineFormset est trop verrouillé pour permettre cela? Mon test "ding" d'impression se déclenche comme prévu, je peux imprimer le formulaire.fields et les voir tous là, mais les champs réels ne sont jamais rendus dans l'admin.Comment ajouter des champs personnalisés à 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) 

Répondre

1
model = models.Progress 

Dans l'administration il n'y aura que les champs définis dans ce modèle Progress. Vous n'avez pas d'option fields/fieldsets qui l'écrase.

Si vous voulez ajouter les nouveaux, il y a deux options:

  • Dans la définition du modèle, ajouter ces nouveaux champs supplémentaires (! Les rendre en option)
  • Dans le modèle d'administration (admin.TabularInline), ajouter quelque chose quelque chose comme:

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

Jetez un oeil à fields, fieldsets.

+0

pas ce que j'espérais entendre, mais oh bien. Au moins c'est confirmé. – Soviut

4

Je l'ai fait une autre façon:

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 

Cela fonctionne jusqu'à présent, je ne ai besoin de passer outre en quelque sorte la méthode de sauvegarde gérer ce nouveau domaine. Voir ceci: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#form. Il dit que par défaut Inlines utilise BaseModelForm, qui est envoyé à formset_factory. Cela ne fonctionne pas pour moi, a essayé de sous-classer BaseModelForm avec des erreurs (aucun attribut '_meta'). Donc j'utilise ModelForm à la place.

+0

Merci pour cette réponse. Avez-vous plus d'informations sur ce que vous avez fait pour annuler la sauvegarde pour Inline Formset? –

+0

Non, cela n'a pas fonctionné pendant des années ... – alekwisnia

+2

Vous voulez mentionner que la partie 'label = 'est très importante. Sans cela, il y a une erreur 'AttributeError: Impossible de rechercher 'my_new_field'' – TitanFighter

2

Vous pouvez le faire par une autre façon (formes dynamiques):

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

Bon exemple, mais ne fonctionne pas dans 1.10.2. De l'exemple de @ alekwisnia j'ai trouvé que sans label = 'new_field ne fonctionne pas. Comment \ où ajouter le 'label' dans votre exemple? Merci. – TitanFighter

Questions connexes