2014-05-22 14 views
6

Ho notato una cosa che non so se è un problema reale o sto facendo un disegno sbagliato.Django form integrityerror per operazioni simultanee su campi univoci

Ho un modello:

class A(Model): 
    name = CharField(unique=True, max_length=255) 

e un ModelForm legato ad A, questo ModelForm ha un metodo di clean_name(), che controlla se quel campo è unico nel db (ignorare il fatto che modelforms già fanno che per impostazione predefinita, sto specificando che per l'esempio qui).

Nella vista se faccio

o = form.save(commit=False) 
# xyz 
o.save() 

in #xyz Ho altro cliente che inserisce un Un oggetto con lo stesso valore name campo, o.save() innesca un'eccezione Integrityerror, impedendo correttamente il record duplicato da inserire .

Quello che voglio sapere è come gestire quei casi, dovrei avvolgere quello o.save() con un try/except block e quindi compilare il campo di errore sul modulo specificando di scegliere un altro valore name?

Questo è in qualche modo un caso comune che dovrebbe accadere a tutti e quella soluzione è orribile, quindi penso che sto facendo qualcosa di terribilmente sbagliato.

+0

Perché non basta: o = form.save()? In questo modo la prossima voce non passerà alla validazione del modulo. – cchristelis

+0

@cchristelis in questo caso #xyz sarebbe tra form.is_valid() e form.save(). – DRC

+0

Una soluzione alternativa è di salvare prima l'oggetto (usando i valori fittizi se alcuni campi obbligatori sono calcolati in 'xyz'), e avere un campo bool chiamato' calculating' che si imposta a 'True' quando si fa' xyz'. Quando il lavoro extra è terminato, puoi aggiornarlo/cancellarlo a seconda del risultato di 'xyz', e impostare' calcolo 'su False. Comunque sia il tuo suggerimento che il mio sono piuttosto schifosi, quindi speriamo che qualcun altro possa suggerire un modo migliore di farlo. –

risposta

0

ho il sospetto che questo potrebbe essere il caso:

forme del modello forniscono convalida l'unicità solo quando viene impostato un flag in xx_clean(). Se si sostituisce lo clean con il proprio (come si ha), è necessario chiamare lo clean() della superclasse. Vedi overwriting the clean method.

Problemi correlati