web-dev-qa-db-fra.com

quand utiliser pre_save, save, post_save dans django?

Je vois que je peux remplacer ou définir pre_save, save, post_save pour faire ce que je veux quand une instance de modèle est enregistrée.

Laquelle est préférée dans quelle situation et pourquoi?

27
eugene

Je ferai de mon mieux pour l'expliquer avec un exemple:

pre_save et post_save sont signaux qui sont envoyés par le modèle. En termes plus simples, les actions à effectuer avant ou après le save du modèle sont appelées.

A savedéclenche les étapes suivantes

  • Emettez un signal de pré-sauvegarde.
  • Prétraitez les données.
  • La plupart des champs ne font pas de prétraitement - les données de champ sont conservées telles quelles.
  • Préparez les données pour la base de données.
  • Insérez les données dans la base de données.
  • Emettez un signal post-sauvegarde.

Django fournit un moyen de remplacer ces signaux.

Maintenant,

pre_save le signal peut être surchargé pour certains traitements avant que la sauvegarde réelle dans la base de données ne se produise - Exemple: (Je ne connais pas un bon exemple de l'emplacement pre_save serait idéal en haut de ma tête)

Disons que vous avez un ModelA qui stocke la référence à tous les objets de ModelB qui n'ont pas encore été modifiés. Pour cela, vous pouvez enregistrer un pre_save signal pour notifier ModelA juste avant que la méthode ModelBsave soit appelée (rien ne vous empêche d'enregistrer un post_save signal ici aussi).

Maintenant, la méthode save (ce n'est pas un signal) du modèle est appelée - Par défaut, chaque modèle a une méthode save, mais vous pouvez la remplacer:

class ModelB(models.Model):
    def save(self):
        #do some custom processing here: Example: convert Image resolution to a normalized value
        super(ModelB, self).save()

Ensuite, vous pouvez enregistrer le post_save signal (Ceci est plus utilisé que pre_save)

Une utilisation courante est UserProfile création d'objet lorsque User objet est créé dans le système.

Vous pouvez enregistrer un post_save signal qui crée un objet UserProfile qui correspond à chaque User du système.

Les signaux sont un moyen de garder les choses modulaires et explicites. (Informer explicitement ModelA si je save ou changer quelque chose dans ModelB)

Je penserai à des exemples plus concrets du monde réel pour tenter de mieux répondre à cette question. En attendant, j'espère que cela vous aidera

26
karthikr
pre_save

il est utilisé avant l'enregistrement de la transaction.

post_save

il est utilisé après l'enregistrement de la transaction.

Vous pouvez utiliser pre_save par exemple si vous avez un FileField ou un ImageField et voyez si le file ou le image existe vraiment.

Vous pouvez utiliser post_save lorsque vous avez un UserProfile et que vous souhaitez en créer un nouveau au moment où un nouveau User est créé.

4

N'oubliez pas le risque de récursions. Si vous utilisez la méthode post_save avec instance.save () appel, au lieu de la méthode .update, vous devez déconnecter votre signal post_save:

Signal.disconnect (receiver = None, sender = None, dispatch_uid = None) [source] Pour déconnecter un récepteur d'un signal, appelez Signal.disconnect (). Les arguments sont tels que décrits dans Signal.connect (). La méthode renvoie True si un récepteur a été déconnecté et False sinon.

L'argument récepteur indique le récepteur enregistré à déconnecter. Il peut être None si dispatch_uid est utilisé pour identifier le destinataire.

... et reconnectez-le après.

pdate () la méthode n'envoie pas de signaux pré_ et post_, gardez cela à l'esprit.

2
SlowSuperman