Django - substitution de la Modèle.méthode create ()?
La Django docs seulement une liste d'exemples pour remplacer save()
et delete()
. Cependant, j'aimerais définir traitement supplémentaire pour mes modèles seulement quand ils sont créés. Pour quiconque est familier avec les Rails, il serait l'équivalent de la création d'un :before_create
filtre. Est-ce possible?
Vous devez vous connecter pour publier un commentaire.
Primordial
__init__()
serait de provoquer l'exécution de code à chaque fois que le python de la représentation de l'objet est instancié. Je ne sais pas les rails, mais un:before_created
filtre me semble que c'est un code à exécuter lorsque l'objet est créé dans la base de données. Si vous souhaitez exécuter du code lorsqu'un nouvel objet est créé dans la base de données, vous devez remplacersave()
, de vérifier si l'objet a unepk
attribut ou pas. Le code devrait ressembler à quelque chose comme ceci:create
? C'est une solution intéressante, mais il ne fonctionne pas dans les cas où l'objet est créé à l'aide deObject(**kwargs).save()
ou toute autre variation sur ce point.super(MyModel, self).save(*args, **kwargs)
?self.pk
n'est pas la meilleure option pour vérifier si l'objet est nouvellement créé ou juste une mise à jour. Parfois, vous fournir l'id de l'objet au moment de la création (une mesure non-base de données de la valeur générée commeKSUID
), et il va provoquer cette clause ne jamais exécuter... Il n'y aself._state.adding
valeur assurez-vous si c'est de l'épargne pour la première fois ou tout simplement la mise à jour, ce qui aide dans ces cas.un exemple de comment créer un post_save signal (à partir de http://djangosnippets.org/snippets/500/)
voici une discussion réfléchie de savoir s'il est préférable d'utiliser des signaux personnalisés ou enregistrer des méthodes https://web.archive.org/web/20120815022107/http://www.martin-geber.com/thought/2007/10/29/django-signals-vs-custom-save-method/
À mon avis, à l'aide de signaux pour cette tâche est plus robuste, plus facile à lire, mais plus long.
instance.save()
. Donc dans ce cas, il y a aussi une perte de performance, car il y aura un INSERT et une requête de mise à JOUR de la base de données.C'est vieux, a accepté de répondre ça fonctionne (Zach), et une plus idiomatique de trop (Michael Bylstra s), mais depuis c'est toujours le premier résultat sur Google la plupart des gens voir, je pense que nous avons besoin d'une plus pratiques exemplaires modernes-django style de réponse ici:
Le point est ceci:
@classmethod
au lieu de@staticmethod
parce que le plus probable que vous allez finir par avoir besoin de consulter les membres de classe statiques dans le codeMême plus propre serait, si les Django auraient une réelle
post_create
signal. (À mon humble avis, si vous avez besoin de passer un booléen arg pour un changement de comportement d'une méthode, qui devrait être de 2 méthodes.)Pour répondre à la question littéralement, le
create
méthode dans un modèle du manager est un moyen standard pour créer de nouveaux objets dans Django. Pour remplacer, faire quelque chose commeDans cet exemple, je suis à la substitution de la Gestionnaire de la méthode de
create
méthode pour faire du traitement supplémentaire avant que l'instance est en fait créé.REMARQUE: Code comme
my_new_instance = MyModel.objects.create(my_field='my_field value')
exécutera cette modifiée
create
méthode, mais le code commemy_new_unsaved_instance = MyModel(my_field='my_field value')
ne sera pas.
Primordial
__init__()
vous permettra d'exécuter du code lorsque le modèle est instancié. N'oubliez pas d'appeler le parent__init__()
.Vous pouvez remplacer la méthode de création d'un gestionnaire ou d'ajouter un classmethod sur le modèle de la classe. https://docs.djangoproject.com/en/1.11/ref/models/instances/#creating-objects
Préféré réponse est correcte, mais le test pour savoir si l'objet est créé ne fonctionne pas si votre modèle de dérive de UUIDModel. Le pk champ ont déjà une valeur.
Dans ce cas, vous pouvez le faire:
already_created = MyModel.objects.filter(pk=self.pk).exists()