Résolue

Args et kwargs dans surcharge de la méthode save pur slugify()

# Méthodes # Héritage # Django

Bonjour, je ne comprends pas très bien ce qu'on capture dans la surcharge de la méthode save ici :

def save(self,*args,**kwargs):
  if not self.slug:
    self.slug = slugify(self.title)
  super().save(*args,**kwargs)

Ce que j'ai compris c'est qu'on capture des arguments qu'on transfère à la méthode save de la super classe Model... Mais c'est quoi les arguments dans ce cas ? Les tuples args et le dictionnaire kwargs contiennent quoi ? Je ne comprends pas

Thibault houdon

Mentor

Salut Yanis !

Je comprends ta confusion, je me posais la même question à l'époque ;)

Ce qu'il faut comprendre c'est que args et kwargs sont là pour récupérer et passer en bout de ligne tous les arguments positionnels et nommés qu'on pourrait passer à la méthode save quand tu l'appelle depuis une instance.

Tu vas me dire dans ce cas, pourquoi ne pas les mettre explicitement plutôt que de mettre des termes génériques comme args et kwargs ? Tout simplement parce que ça serait trop long et compliqué à chaque fois que tu fais une surcharge, d'aller voir la définition précise de la fonction de base, pour la remettre à l'identique dans ta fonction. Et ça permet aussi d'avoir un code plus évolutif.

Si on reprend l'exemple de save, tu peux voir dans la documentation qu'il y a pas mal de paramètres :

Model.save(force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS, update_fields=None)

Du coup, si tu n'utilises pas args et kwargs, il faudrait que tu recopies cette définition, c'est un peu pénible :

def save(self, force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS, update_fields=None):
  if not self.slug:
    self.slug = slugify(self.title)
  super().save(*args,**kwargs)

Là encore tu pourrais me dire "quel est l'intérêt de recopier les paramètres ?".

Parce que sinon ils n'existeront plus dans ta méthode save. Ça signifie que sans surcharger la méthode save, quelqu'un pourrait faire :

blog_post.save(force_insert=True)

Mais si dans ta surcharge tu fais seulement :

def save(self):
  if not self.slug:
    self.slug = slugify(self.title)
  super().save()

Sans mettre les args et kwargs et sans mettre le paramètre force_insert à la main, tu auras une erreur qui t'indiqueras que ta fonction save n'accepte pas de paramètre force_insert.

L'intérêt d'utiliser args et kwargs aussi c'est d'avoir une fonction qui sera toujours valide. Imagine que tu mettes tous les arguments à la main et que dans une version future de Django, les développeurs du framework ajoutent un paramètre. Tu devrais le rajouter toi aussi dans toutes tes méthodes save surchargées 🥵 Là encore, pas très pratique.

Voilà donc les principales raisons du args et kwargs : ça te permet d'avoir un code qui reste valide peu importe l'évolution du code de base que tu surcharges, et ça t'évite de devoir écrire tous les arguments positionnels et / ou nommés à la main :)

J'espère que c'est plus clair !

C'est super() clair ! Merci pour ta réponse qui répond même à des questions que je ne m'étais pas posé.

J'ai une autre question, lorsqu'on surcharge la méthode save, qu'on crée l'instance avec la classe et qu'on fait save, le slug est modifié... Mais quand on crée l'instance avec objects.create() ça ne fonctionne pas, la méthode save n'est pas exécuté automatiquement avec create ? Ça passe par autre chose la sauvegarde dans la bdd avec objects.create ?

Thibault houdon

Mentor

Salut Yanis !

Normalement oui, la méthode save est appelée, est-ce que tu peux montrer le code que tu utilises pour créer ton instance et le code de ta méthode save (voire de tout ton modèle).

Merci !

C'etait par rapport à l'exemple dans la formation sur les modèles mais ça marche maintenant que je viens d'essayer, je ne sais pas c'etait quoi le problème tout à l'heure. Bizarre... Désolé !

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.