2010-02-10 29 views
14

Come si aggiungono errori all'inizio di un modulo dopo aver pulito i dati? Ho un oggetto che deve effettuare una chiamata REST a un'app esterna (google maps) come condizione di pre-salvataggio, e questo può fallire, il che significa che ho bisogno che i miei utenti correggano i dati nel modulo. Così ho pulito i dati e quindi provare a salvare e aggiungere alle errori di forma, se il salvataggio non funziona:aggiungendo errori agli errori di forma di Django .__ all__

if request.method == "POST": 
#clean form data 
    try: 
     profile.save() 
     return HttpResponseRedirect(reverse("some_page", args=[some.args])) 
    except ValueError: 
     our_form.errors.__all__ = [u"error message goes here"] 
return render_to_response(template_name, {"ourform": our_form,}, 
     context_instance=RequestContext(request)) 

Questa non è riuscito a restituire il testo di errore nel mio unità di test (che sono stati alla ricerca di essa in {{form.non_field_errors}}), e poi quando lo eseguo attraverso il debugger, gli errori non sono stati aggiunti all'errore di form dei caratteri quando raggiungono la riga render_to_response, né da nessun'altra parte nella struttura our_form. Perché non ha funzionato? Come posso aggiungere errori all'inizio di un modulo dopo che è stato pulito?

risposta

9

Si consiglia di aumentare il validationerror.

perché non mettere la verifica all'interno del metodo pulito del form

class ProfileForm(forms.Form): 
    def clean(self): 
     try: 
      #Make a call to the API and verify it works well 
     except: 
      raise forms.ValidationError('Your address is not locatable by Google Maps') 

in questo modo, è sufficiente lo standard form.is_valid() nella vista.

+1

Sfortunatamente deve essere più sistematico, questo aggiornamento può accadere quando altre parti del sistema cercano di alterare i dati, quindi va oltre il solo modulo. Altrimenti, hai ragione, la forma sarebbe l'ideale. – hendrixski

+0

Non dovrebbe sempre usare i moduli ereditati per fare convalide? –

18

Si vuole davvero farlo durante la validazione del form e generare un ValidationError da lì ... ma se si è pronti a farlo in questo modo, si vorrà accedere a _errors per aggiungere nuovi messaggi. Provare qualcosa di simile:

from django.forms.util import ErrorList 

our_form._errors["field_name"] = ErrorList([u"error message goes here"]) 
+0

Ho bisogno degli errori nella parte superiore del modulo perché non è un campo che potrebbe causare il fallimento di questo (ad esempio sto combinando street + city + state + zipcode e geocoding it). – hendrixski

+6

-1 perché questo non risolve il requisito dell'OP di aggiungere un errore * non-campo *. Inoltre -1 perché questo compito cancella tutti gli errori che possono essere già esistiti per '_errors [" nome_campo "]'. – JCotton

+0

Questo sarà il modo giusto per farlo? non_field_errors = [] self._errors ['field_name'] = self._errors.get ('field_name', []) self._errors ['field_name'] = self._errors ['field_name']. Append (_ ("field_name non valido") #add anyy errore non campo raise form.ValidationError (non_field_errors) –

1

io non sono sicuro di come orribile di un hack questo è (ho veramente solo lavorato su due progetti Django fino a questo punto), ma se si fa una cosa del genere segue si ottiene un messaggio di errore a parte che non è associato con un campo specifico nel modello:

form = NewPostForm() 
if something_went_horribly_wrong(): 
    form.errors[''] = "You broke it!" 
12

errori non sul campo possono essere aggiunti utilizzando la chiave NON_FIELD_ERRORS costante dizionario (che è __all__ per impostazione predefinita):

from django import forms 
errors = my_form._errors.setdefault(forms.forms.NON_FIELD_ERRORS, forms.util.ErrorList()) 
errors.append("My error here") 
+2

Ciò causa che un oggetto 'NoneType' non ha alcun attributo 'setdefault' per me. Probabilmente il mio modello è altrimenti valido, e quindi _errors è indefinito Qualche idea? –

+0

Ha funzionato bene per me. Grazie! – urig

+2

@MartinProbst: questo codice deve essere eseguito dopo una chiamata a form.is_valid() –

8

Sei quasi arrivato con la tua soluzione originale. Ecco una classe Form di base che ho costruito, che mi permette di fare la stessa cosa, cioè aggiungere messaggi di errore non di campo al modulo:

from django import forms 
from django.forms.util import ErrorDict 
from django.forms.forms import NON_FIELD_ERRORS 

class MyBaseForm(forms.Form): 
    def add_form_error(self, message): 
     if not self._errors: 
      self._errors = ErrorDict() 
     if not NON_FIELD_ERRORS in self._errors: 
      self._errors[NON_FIELD_ERRORS] = self.error_class() 
     self._errors[NON_FIELD_ERRORS].append(message) 

class MyForm(MyBaseForm): 
    .... 

Tutte le mie forme estendono questa classe e così posso semplicemente chiamare l'add_form_error () metodo per aggiungere un altro messaggio di errore.

+0

+1 per verificare che gli attributi esistano e non assumendo che 'error_class()' è una ErrorList. È possibile utilizzare questo metodo per aggiungere messaggi di errore non di campo anche senza su Modulo di bclassing, che può essere adatto ad altri casi d'uso. – JCotton

+0

1.7 ha qualcosa del genere. –

0

Se la convalida riguarda il livello dati, non utilizzare la convalida del modulo. Dal momento che Django 1.2, tuttavia, esiste un concetto simile per i modelli Django e questo è sicuramente quello che usi. Vedi the documentation for model validation.

10

In Django 1.7 o superiore, lo farei:

form.add_error(field_name, "Some message") 

Il metodo add_error è stato aggiunto in 1.7. La variabile form è la forma che desidero manipolare e field_name è il nome del campo specifico o None se desidero un errore non associato a un campo specifico.

In Django 1.6 Vorrei fare qualcosa di simile:

from django.forms.forms import NON_FIELD_ERRORS 

errors = form._errors.setdefault(field_name, form.error_class()) 
errors.append("Some message") 

Nel codice sopra form è la forma che voglio manipolare e field_name è il nome del campo per il quale voglio aggiungere un errore. field_name può essere impostato su NON_FIELD_ERRORS per aggiungere un errore non associato a un campo specifico. Io uso form.error_class() per generare la lista vuota dei messaggi di errore. Ecco come Django 1.6 crea internamente una lista vuota invece di istanziare direttamente ErrorList().

+0

Hey Louis, grazie mille per questa risposta, fantastico! –

+0

@Louis, il mio è 1.8, ho provato "form.add_error (field_name," Some message ")", quindi segnala "l'oggetto" MyForm "non ha attributo 'addError'", devo importare qualcosa a parte "da django.core.exceptions import ObjectDoesNotExist, ValidationError "? –

Problemi correlati