2010-10-11 15 views
6

Ho un modulo Django che aggiungerà una voce a un database con un vincolo univoco su una delle colonne. Se l'invio avviene per tentare la creazione di un duplicato, ottengo un valore django.db.utls.IntegrityError affermando che ho violato il vincolo univoco (per fortuna).Aggiunge esternamente errori di modulo in Django

Durante l'elaborazione di forme Django, ci sono un certo numero di modi per validare:

  1. Override classe form clean metodo
  2. Override classe form clean_<field> metodo

Se il clear_<field> metodo solleva un django.forms.ValidationError, il messaggio di errore verrà aggiunto a un elenco nel dizionario _errors sotto il nome del campo. Quando si utilizza il metodo clean, gli errori devono essere manually inserted nel codice _errors.

Ora, i clean e clean_<field> metodi non suonano come un bel posto per inserire il codice che ha effetti collaterali, e temo che il controllo in questo momento se il valore è unico non garantisce non voglio entrare IntegrityError s . Preferirei effettivamente provare e creare la riga nel database e segnalare un errore di modulo quando viene violato un vincolo.

Il mio problema principale è che i moduli espongono una proprietà pubblica errors che è di sola lettura. Pertanto, dovrei, secondo i documenti, aggiungere un metodo nel mio modulo che faccia tutto il lavoro, provare ad inserire nel database e registrare un errore quando viene sollevato uno IntegrityError. Poiché l'azione che elabora il modulo dopo la convalida richiede molti altri dati, non voglio inserire il codice all'interno della classe del modulo stesso.

C'è qualche altro modo (documentato o meno) per aggiungere una voce nel errors dict al di fuori della classe, o dovrei semplicemente accedere alla variabile "privata" _errors e accontentarla? So che sembra una violazione dell'OOP, ma creare un metodo extra solo per accedere a questa variabile "privata" non mi sembra come se proteggesse qualcuno da qualsiasi cosa.

Edit: Sembra come qualcun altro ha già sollevato a similar question, ma sembra le risposte hanno indicato inserimento manuale in _errors ...

+0

possibile duplicato di [. Aggiungere errori ad errori di forma Django \ _ \ _ all \ _ \ _] (http: // stackoverflow.com/questions/2235146/adding-errors-to-django-form-errors-all) – Louis

risposta

7

Per ora, una soluzione semplice è la seguente:

try: 
    # Try to save model instance, which might throw `IntegrityError`. 
    # ... 
except django.db.utils.IntegrityError: 
    # The form passed validation so it has no errors. 
    # Use the `setdefault` function just in case. 
    errors = django.forms.util.ErrorList() 
    errors = form._errors.setdefault(
     django.forms.forms.NON_FIELD_ERRORS, errors) 
    errors.append('Sorry, this username is already in use.') 
0

Penso che l'aggiunta del metodo per la forma è abbastanza ragionevole. La classe ModelForm, che ha un metodo save() che esegue la logica di salvataggio dell'istanza creata nel database. Se il tuo modulo può ereditare da ModelForm (o semplicemente aggiungere un metodo save() al tuo modulo), sarai comunque all'interno degli standard "djangonian".

http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method

+0

So che è ragionevole, ma non posso farlo in questo caso particolare. Il modulo viene utilizzato in diversi luoghi e, in un caso, i dati del modulo vengono passati a un'altra entità tramite un'invocazione polimorfica. Nel disegno attuale, il modulo * non dovrebbe * sapere cosa fare con i dati! –

Problemi correlati