2012-08-05 2 views
8

Disons que j'ai une classe nommée Héros avec un champ nommé "nom". Chaque fois qu'un nouvel objet Hero est créé, je veux ajouter " is a hero". Puis-je utiliser __init__ pour cela? Ou y a-t-il une méthode spécifique à django que je peux remplacer pour cela?Modèle django sur créer 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

Ce n'est presque jamais ce que vous voulez. Décrivez votre vrai problème. –

+0

@ IgnacioVazquez-Abrams Je dois mettre à jour un autre modèle qui est basé sur l'entrée agrégée de ma classe 'Hero'. – Joey

+1

@Joey Utilisez [signaux] (https://docs.djangoproject.com/fr/1.4/topics/signals/) à la place. – Dougal

Répondre

15

Si par « chaque fois qu'un nouvel objet Hero est créé » vous voulez dire « chaque fois qu'un enregistrement Hero est créé dans la base de données », alors non, vous ne voulez pas le faire dans la méthode __init__, puisque cela est appelé à chaque fois qu'un objet Héros est créé en Python, y compris lorsque vous venez d'obtenir un enregistrement existant de la base de données. Pour faire ce que vous voulez, vous pouvez utiliser le post_save signal de Django, en vérifiant dans le rappel de signal que le paramètre de mot-clé created a la valeur True et en exécutant votre logique "on creation" si c'est le cas.

Alternativement, et plus simple et naturel dans certains cas, vous pouvez remplacer la méthode de Hero save() comme suit:

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) 

Notez que la méthode bulk_create de Djagno sautera déclenchement soit le signal post-enregistrement ou en appelant save.

+4

Comme [les documents expliquent] (https://docs.djangoproject.com/fr/1.4/topics/db/models/#overriding-model-methods), vous devriez toujours inclure '* args' et' ** kwargs' dans l'appel à la méthode 'save' de la classe parente, * ie *' super (Hero, self) .save (* args, ** kwargs) '. La raison de ceci est d'anticiper les changements (dans Django, ou votre code) à la signature de la méthode 'save()'. – supervacuo

+1

@supervacuo - bonne prise, j'ai édité cela, merci. – Ghopper21

+1

En guise d'avertissement pour les futurs lecteurs, l'écrasement de 'save' n'est pas universellement sûr. [Les sauvegardes par lots n'appellent pas de méthodes de sauvegarde surchargées ou n'appellent pas les signaux 'post_save' et' pre_save' (https://docs.djangoproject.com/fr/dev/topics/db/models/#overriding-model-methods). Je ne suis pas sûr que Django fournisse un moyen de personnaliser la mise à jour ou la création en masse, même si ça ne ressemble pas à ça, alors vous devriez faire attention à la façon de faire et éviter les sauvegardes en masse si vous défendez sur le comportement de mise à jour personnalisée. – Taywee

Questions connexes