Je veux déclencher une action spéciale dans la méthode save () d’un object modèle Django lorsque je sauvegarde un nouvel enregistrement (sans mettre à jour un enregistrement existant).
Le chèque pour (self.id! = None) est-il nécessaire et suffisant pour garantir que l’auto-enregistrement est nouveau et n’est pas mis à jour? Des cas particuliers que cela pourrait négliger?
self.pk is None:
renvoie True dans un nouvel object Model, à moins que l’object ait un UUIDField
tant que primary_key
.
Le cas le plus inquiétant est de savoir s’il existe des contraintes d’unicité sur les champs autres que l’identifiant (par exemple, des index uniques secondaires sur d’autres champs). Dans ce cas, vous pouvez toujours avoir un nouvel enregistrement, mais ne pas pouvoir le sauvegarder.
Une autre façon de vérifier self.pk
nous pouvons vérifier self._state
du modèle
self._state.adding is True
création self._state.adding is True
self._state.adding is False
mise à jour self._state.adding is False
Je l’ai eu de cette page
Vérifier self.id
suppose que l’ id
est la clé primaire du modèle. Une manière plus générique serait d’utiliser le raccourci pk .
is_new = self.pk is None
La vérification de self.pk == None
n’est pas suffisante pour déterminer si l’object va être inséré ou mis à jour dans la firebase database.
Le système O / RM de Django présente un piratage particulièrement désagréable qui consiste essentiellement à vérifier s’il y a quelque chose à la position PK et, le cas échéant, à effectuer une mise à jour INSERT (ceci est optimisé pour INSERT si la PK est Aucune).
La raison pour laquelle cela doit être fait est que vous êtes autorisé à définir la PK lorsqu’un object est créé. Bien que cela ne soit pas courant lorsque vous avez une colonne de séquence pour la clé primaire, cela ne s’applique pas aux autres types de champs de clé primaire.
Si vous voulez vraiment savoir, vous devez faire ce que fait l’O / RM et regarder dans la firebase database.
Bien sûr, vous avez un cas spécifique dans votre code et pour cela, il est fort probable que self.pk == None
vous indique tout ce que vous devez savoir, mais ce n’est pas une solution générale.
Vous pouvez simplement vous connecter au signal post_save qui envoie un kwargs “créé”, si true, votre object a été inséré.
http://docs.djangoproject.com/en/stable/ref/signals/#post-save
self.id
et l’indicateur force_insert
.
if not self.pk or kwargs.get('force_insert', False): self.created = True # call save method. super(self.__class__, self).save(*args, **kwargs) #Do all your post save actions in the if block. if getattr(self, 'created', False): # So something # Do something else
C’est pratique car votre nouvel object (self) a la valeur pk
Je suis très en retard sur cette conversation, mais j’ai rencontré un problème avec le fichier self.pk qui est associé à une valeur par défaut.
La façon dont j’ai contourné cela est d’append un champ date_created au modèle
date_created = models.DateTimeField(auto_now_add=True)
De là, vous pouvez aller
created = self.date_created is None
utilisez plutôt pk au lieu de id :
if not self.pk: do_something()
Pour une solution qui fonctionne également même lorsque vous avez une clé primaire UUIDField
(ce que d’autres ont noté n’est pas None
si vous remplacez simplement la save
), vous pouvez vous connecter au signal post_save de Django. Ajoutez ceci à vos models.py :
from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save, sender=MyModel) def mymodel_saved(sender, instance, created, **kwargs): if created: # do extra work on your instance, eg # instance.generate_avatar() # instance.send_email_notification() pass
Ce rappel bloque la méthode de save
, vous pouvez donc faire des choses comme déclencher des notifications ou mettre à jour le modèle avant que votre réponse ne soit renvoyée sur le réseau, que vous utilisiez des formulaires ou la structure REST Django pour les appels AJAX. Bien entendu, utilisez les tâches lourdes et responsables dans une queue plutôt que d’attendre que vos utilisateurs attendent 🙂
C’est la manière commune de le faire.
l’identifiant sera donné lors de la première sauvegarde de la firebase database
Pour savoir si vous mettez à jour ou insérez l’object (data), utilisez self.instance.fieldname
dans votre formulaire. Définissez une fonction propre dans votre formulaire et vérifiez si la valeur actuelle est identique à la précédente, sinon vous la mettez à jour.
self.instance
et self.instance.fieldname
comparer avec la nouvelle valeur