2009-09-23 20 views
8

Ho una semplice ModelForm:Elimina i campi da ModelForm

class MyForm(ModelForm): 

    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     del self.fields['name'] 

Come potete vedere, cerco di rimuovere un campo dalla lista dei campi del form (il campo esiste definitivamente nel modello), ma ottengo un eccezione:

TemplateSyntaxError at [..] 

Caught an exception while rendering: "Key 'name' not found in Form" 

non ho scritto un modulo personalizzato, in modo che il modello in cui si verifica l'errore è:

/templates/admin/includes/fieldset.html, error at line 4 

Tutte le idee?

- AGGIORNAMENTO -

Il problema appare solo nel settore amministrativo.

- UPDATE 2 -

Forse una discarica traccia dà più informazioni:

Original Traceback (most recent call last): 
    File "/Library/Python/2.5/site-packages/django/template/debug.py", line 71, in render_node 
    result = node.render(context) 
    File "/Library/Python/2.5/site-packages/django/template/defaulttags.py", line 155, in render 
    nodelist.append(node.render(context)) 
    File "/Library/Python/2.5/site-packages/django/template/defaulttags.py", line 239, in render 
    value = bool_expr.resolve(context, True) 
    File "/Library/Python/2.5/site-packages/django/template/__init__.py", line 546, in resolve 
    obj = self.var.resolve(context) 
    File "/Library/Python/2.5/site-packages/django/template/__init__.py", line 687, in resolve 
    value = self._resolve_lookup(context) 
    File "/Library/Python/2.5/site-packages/django/template/__init__.py", line 722, in _resolve_lookup 
    current = current() 
    File "/Library/Python/2.5/site-packages/django/contrib/admin/helpers.py", line 81, in errors 
    return mark_safe(u'\n'.join([self.form[f].errors.as_ul() for f in self.fields]).strip('\n')) 
    File "/Library/Python/2.5/site-packages/django/forms/forms.py", line 105, in __getitem__ 
    raise KeyError('Key %r not found in Form' % name) 
KeyError: "Key 'name' not found in Form" 

Nel settore amministrativo, io uso il Grapelli-tema. Forse questo ha a che fare con il problema?

+0

Magicamente ™ funziona ora, anche se non so perché. Grazie comunque per il tuo aiuto. – schneck

risposta

0

È possibile utilizzare la proprietà escludere per rimuovere campi da un ModelForm

exclude = ('field_name1', 'field_name2,) 
+1

Lo so, ma devo rimuovere i campi dinamicamente. – schneck

0

Una causa che posso pensare è se la classe ModelAdmin che utilizza il modulo personalizzato ha impostazioni in conflitto. Ad esempio, se hai specificato esplicitamente il campo "nome" all'interno di "campi" o "campi" del tuo ModelAdmin.

+0

no, ho avuto un aspetto più approfondito nel codice, non ci sono riferimenti duri come questo. – schneck

6

Come descritto in Creating forms from models - Selecting the fields to use, ci sono tre modi:

  1. Nel modello, impostare editable=False. Tutti i moduli creati dal modello escluderanno il campo.
  2. Definire l'attributo fields nella classe interna Meta per includere solo i campi desiderati.
  3. Definire l'attributo exclude nella classe interna Meta per elencare i campi che non si desidera.

Quindi, se il modello dispone di campi field1, field2, e field3 e non si vuole field3, tecnica # 2 sarebbe simile a questa:

class MyModelForm(ModelForm): 
    class Meta: 
     model = MyModel 
     fields = ('field1', 'field2') 

e la tecnica # 3 sarebbe simile a questa:

class MyModelForm(ModelForm): 
    class Meta: 
     model = MyModel 
     exclude = ('field3',) 
+3

Come ho già scritto nel mio commento sopra, devo rimuovere i campi in modo dinamico, significa, nel metodo __init __-. Pertanto non è possibile utilizzare i metodi suggeriti. – schneck

+0

Cosa intendi rimuovendo i campi "dinamicamente"? – Selene

+1

@Selene: ciò significa che i campi che verranno visualizzati (/ validati/salvati) sono determinati in fase di esecuzione, non in fase di progettazione – schneck

13

Ho avuto lo stesso problema. Ecco come ho fatto lavorare nel nuovo Django (tronco):

class MyModelAdmin(admin.ModelAdmin): 
    # Your stuff here.. 

    def get_form(self, request, obj=None, **kwargs): 
     if request.user.is_staff: # condition 
      self.exclude = ('field',) 
     return super(PublishAdmin, self).get_form(request, obj=obj, **kwargs) 

Con l'override del metodo get_form e mettendo la logica qui è possibile selezionare quali Form si desidera visualizzare. Sopra ho visualizzato il modulo standard quando una condizione è stata soddisfatta.

+2

Wow, ovviamente, ha senso. Questo è il modo in cui l'ho adattato per il mio uso: a) inizializzare 'MyModelAdmin' con' exclude = [] '(o qualsiasi cosa sia esclusa dalla base) e quindi fare' self.exclude.append ('campo') 'quando le condizioni sono soddisfatte . – hangtwenty

+0

Anche solo una nota (che non potevo modificare perché era troppo piccola): 'user.is_staff' è una proprietà non un metodo, quindi chiamarla genererà un errore. – hangtwenty

+0

Questa thread è sicura? – frnhr

2

Questo funziona benissimo ...

def __init__(self, instance, *args, **kwargs):  
    super(FormClass, self).__init__(instance=instance, *args, **kwargs) 
    if instance and instance.item: 
     del self.fields['field_for_item'] 
+0

AFAIK field_for_item verrà impostato su none se manca in form.cleaned_data. Fai attenzione: questo potrebbe cancellare i valori nella colonna db field_for_item! – guettli