2012-08-05 13 views
8

Diciamo che ho una classe di nome Hero con un campo chiamato "nome". Ogni volta che viene creato un nuovo oggetto Hero, voglio aggiungere " is a hero". Posso usare __init__ per quello? O c'è un metodo specifico per il django che posso ignorare per quello?modello django su create use __init__?

class Hero(modes.Model) 
    name = models.CharField(max_length=100) 
    def __init__(self, *args, **kwargs): 
     name += " is a hero" 
     super(Hero, self).__init__(*args, **kwargs) 
+1

Questo non è quasi mai quello che vuoi. Descrivi il tuo vero problema. –

+0

@ IgnacioVazquez-Abrams Devo aggiornare un altro modello che si basa sull'input aggregato della mia classe 'Hero'. – Joey

+1

@Joey Utilizzare invece [segnali] (https://docs.djangoproject.com/en/1.4/topics/signals/). – Dougal

risposta

15

Se per "ogni volta che viene creato un nuovo oggetto Hero" si intende "ogni volta che un record di eroe viene creato nel database", allora no, non si vuole fare questo nel metodo __init__, poiché ciò viene chiamato ogni volta che viene creato un oggetto Hero in Python, anche quando stai ottenendo un record esistente dal database.

di fare ciò che si desidera, è possibile utilizzare Django di post_save signal, il check-nel callback segnale che il parametro created parola chiave è True ed eseguire la vostra logica "sulla creazione" in caso affermativo.

In alternativa, e più semplice e naturale, in alcuni casi, è possibile ignorare il metodo dell'Eroe save() come segue:

def save(self, *args, **kwargs): 
    if not self.pk: # object is being created, thus no primary key field yet 
     self.name += " is a hero" 
    super(Hero, self).save(*args, **kwargs) 

Si noti che il metodo di Djagno bulk_create salterà innescando sia il segnale post-save o chiamando save.

+4

Come [i documenti spiegano] (https://docs.djangoproject.com/en/1.4/topics/db/models/#overriding-model-methods), dovresti sempre includere '* args' e' ** kwargs' nella chiamata al metodo 'save' della classe genitore, * ie *' super (Hero, self) .save (* args, ** kwargs) '. La ragione di ciò è una prova a prova di futuro contro i cambiamenti (in Django, o il tuo codice) alla firma del metodo 'save()'. – supervacuo

+1

@supervacuo - buona cattura, l'ho modificato, grazie. – Ghopper21

+1

Come avvertimento per i futuri lettori, ignorare 'save' non è universalmente sicuro. [I salvataggi in batch non invocano metodi di salvataggio sovraccarico o chiamano i segnali "post_save' e' pre_save'] (https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods). Non sono sicuro che Django fornisca un modo per personalizzare l'aggiornamento o la creazione di massa, anche se non sembra, quindi dovresti fare attenzione a come lo fai e assicurarti che i salvataggi di massa non avvengano se difendi sul comportamento di aggiornamento personalizzato. – Taywee