Les Django docs listent uniquement des exemples pour remplacer save()
et delete()
. Cependant, j'aimerais définir un traitement supplémentaire pour mes modèles uniquement lorsqu'ils sont créés. Pour ceux qui connaissent Rails, cela équivaudrait à créer un filtre :before_create
. Est-ce possible?
Remplacer __init__()
entraînerait l’exécution de code chaque fois que la représentation python de l’objet est instanciée. Je ne connais pas Rails, mais un filtre :before_created
me semble être du code à exécuter lorsque l'objet est créé dans la base de données. Si vous voulez exécuter du code lorsqu'un nouvel objet est créé dans la base de données, vous devez remplacer save()
, en vérifiant si l'objet a un attribut pk
ou non. Le code ressemblerait à ceci:
def save(self, *args, **kwargs):
if not self.pk:
# This code only happens if the objects is
# not in the database yet. Otherwise it would
# have pk
super(MyModel, self).save(*args, **kwargs)
un exemple sur la façon de créer un signal post_save (from http://djangosnippets.org/snippets/500/ )
from Django.db.models.signals import post_save
from Django.dispatch import receiver
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
"""Create a matching profile whenever a user object is created."""
if created:
profile, new = UserProfile.objects.get_or_create(user=instance)
voici une discussion réfléchie sur le meilleur moyen d'utiliser des signaux ou des méthodes de sauvegarde personnalisées https://web.archive.org/web/20120815022107/http://www.martin-geber.com/thought/2007/10/ 29/Django-signaux-vs-custom-save-method/
À mon avis, l’utilisation de signaux pour cette tâche est plus robuste, plus facile à lire mais plus longue.
Ceci est vieux, a une réponse acceptée qui fonctionne (Zach), et une réponse plus idiomatique aussi (Michael Bylstra), mais comme c'est toujours le premier résultat sur Google, la plupart des gens le voient, Je pense que nous avons besoin de meilleures pratiques modernes -Django style répondre ici:
from Django.db.models.signals import post_save
class MyModel(models.Model):
# ...
@classmethod
def post_create(cls, sender, instance, created, *args, **kwargs):
if not created:
return
# ...what needs to happen on create
post_save.connect(MyModel.post_create, sender=MyModel)
Le point est ceci:
@classmethod
au lieu de @staticmethod
car vous devrez probablement faire référence à des membres statiques de la classe dans le codeMême plus propre serait si Django de base avait un signal post_create
réel. (À mon humble avis, si vous avez besoin de passer un argument booléen pour changer le comportement d'une méthode, cela devrait être 2 méthodes.)
Remplacer __init__()
vous permettra d'exécuter du code lorsque le modèle est instancié. N'oubliez pas d'appeler le __init__()
du parent.
Vous pouvez remplacer la méthode create par un gestionnaire personnalisé ou ajouter une méthode de classe à la classe de modèle. https://docs.djangoproject.com/fr/1.11/ref/models/instances/#creating-objects