Django ModelForm: à quoi sert save (commit=False)?

Pourquoi devrais-je utiliser save(commit=False) au lieu de simplement créer un objet de formulaire à partir de la sous-classe ModelForm et exécuter is_valid() pour valider à la fois le formulaire et le modèle?

En d'autres termes, à quoi sert save(commit=False)?

Si cela ne vous dérange pas, Pourriez-vous fournir des situations hypothétiques où cela pourrait être utile?

53
demandé sur Vaibhav Mule 2012-10-12 01:12:36

4 réponses

C'est utile lorsque vous obtenez la plupart de vos données de modèle à partir d'un formulaire, mais que vous devez remplir certains champs null=False avec des données non-form.

Enregistrer avec commit = False vous obtient un objet modèle, puis vous pouvez ajouter vos données supplémentaires et les enregistrer.

C'est un bon exemple de cette situation.

68
répondu dokkaebi 2017-05-23 11:46:40

Voici la réponse (de docs):

# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)

# Create, but don't save the new author instance.
>>> new_author = f.save(commit=False)

La situation la plus courante est d'obtenir l'instance du formulaire mais seulement "en mémoire", pas dans la base de données. Avant de l'Enregistrer, vous voulez apporter quelques modifications:

# Modify the author in some way.
>>> new_author.some_field = 'some_value'

# Save the new instance.
>>> new_author.save()
22
répondu dani herrera 2012-10-11 21:19:21

À partir des documents Django:

Cette méthode save () accepte un argument de mot-clé commit facultatif, qui accepte soit vrai ou faux. Si vous appelez save () avec commit = False, ensuite, il retournera un objet qui n'a pas encore été enregistré dans la base de données.

Dans ce cas, c'est à vous d'appeler save() sur l'instance de modèle résultante. Ceci est utile si vous voulez faire un traitement personnalisé sur l'objet avant de l'enregistrer, ou si vous voulez utiliser l'un des modèles spécialisés options d'enregistrement. commit est True par défaut.

Il semble que save (commit=False ) crée une instance de modèle, qu'elle vous renvoie. Ce qui est soigné pour un post-traitement avant de l'enregistrer!

5
répondu A.J.Rouvoet 2012-10-11 21:18:50

Comme "exemple réel", considérons un modèle utilisateur où l'adresse e-mail et le nom d'utilisateur sont toujours les mêmes, et vous pouvez alors écraser la méthode de sauvegarde de votre ModelForm comme:

class UserForm(forms.ModelForm):
    ...
    def save(self):
        # Sets username to email before saving
        user = super(UserForm, self).save(commit=False)
        user.username = user.email
        user.save()
        return user

Si vous n'avez pas utilisé commit=False pour définir le nom d'utilisateur sur l'adresse e-mail, vous devrez soit modifier la méthode de sauvegarde du modèle utilisateur, soit enregistrer l'objet utilisateur deux fois (ce qui duplique une opération de base de données coûteuse.)

5
répondu Mark Chackerian 2016-06-14 19:35:43