A question on save_m2m()

1,259 views
Skip to first unread message

Ankush Thakur

unread,
May 14, 2016, 5:43:36 AM5/14/16
to django...@googlegroups.com
So the following section from the docs has me a little confused:

=====================
Another side effect of using commit=False is seen when your model has a many-to-many relation with another model. If your model has a many-to-many relation and you specify commit=False when you save a form, Django cannot immediately save the form data for the many-to-many relation. This is because it isn’t possible to save many-to-many data for an instance until the instance exists in the database.

To work around this problem, every time you save a form using commit=False, Django adds a save_m2m() method to your ModelForm subclass. After you’ve manually saved the instance produced by the form, you can invoke save_m2m() to save the many-to-many form data. For example:

# 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)

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

# Save the new instance.
>>> new_author.save()

# Now, save the many-to-many data for the form.
>>> f.save_m2m()
======================

I can understand why Django doesn't save Many-to-Many data when commit is set to False, but why do we need to  manually call save_m2m() after doing save() manually? Why doesn't Django update the associated Many-to-Many data automatically in this case?


Regards,
Ankush Thakur

James Schneider

unread,
May 18, 2016, 2:45:57 AM5/18/16
to django...@googlegroups.com
Look a bit closer at the process you listed from the docs: 

The initial f.save(commit=False) is run on the bound ModelForm object, and returns an unsaved Author object (new_author), which means that the M2M relations are not saved either (since you can't save a M2M without a fully saved/initialized object already in the DB). 

You are then running save() on new_author, not on f, which means you are saving the primary model instance returned by the form, not saving the form itself.

The last step is the f.save_m2m() call, which tells the form (not new_author) to grab the related objects and tie them to your new_author object, and completes saving all pieces of the form. 

HTH,

-James

Ankush Thakur

unread,
May 18, 2016, 1:00:22 PM5/18/16
to Django users
Ah! Stupid, stupid me. 

Thanks a lot for clarifying! :-)

Best,
Ankush
Reply all
Reply to author
Forward
0 new messages