Code

Opened 2 years ago

Closed 9 months ago

Last modified 9 months ago

#17528 closed Cleanup/optimization (fixed)

Document that add() and remove() with a many-to-many relationship do not call Model.save()

Reported by: mmoya@… Owned by: nobody
Component: Documentation Version: 1.3
Severity: Normal Keywords: m2m, related manager, save
Cc: asendecka@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I think there are an inconsistency in the model's save method. Suppose we are editing an existing object from the admin.
If I want to prevent saving objects (suppose I want to moderate the object), when I override the Model.save() or ModelAdmin.save_model()
the m2m relations are also saved, but what I really want to do is avoid saving any changes.

There is a simple example:

class Topping(models.Model):
    # ...

class Pizza(models.Model):
    # ...
    toppings = models.ManyToManyField(Topping)

    def save(self, *args, **kwargs):
	return

This happens because the related m2m is commited outside the save method.
If I execute this on shell:

>>> p = Pizza.objects.get(pk=5)  
>>> p.foo_field
'Foo text'
>>> t = Pizza.objects.get(pk=1)  
>>> p.foo_field = 'Bar text'
>>> p.toppings.add(t)

Then, the p object have a new topping object added, but i never executed the p.save().

Attachments (1)

17528.diff (1.7 KB) - added by timo 9 months ago.

Download all attachments as: .zip

Change History (6)

comment:1 Changed 2 years ago by ethlinn

  • Cc asendecka@… added
  • Component changed from Database layer (models, ORM) to Documentation
  • Needs documentation set
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

This is expected behaviour - add() method associates models by means of creating a new row in db (in the separate m2m table) - it does not save Pizza but it creates Pizza-Topping relationship.

https://docs.djangoproject.com/en/dev/ref/models/relations/#django.db.models.fields.related.RelatedManager.add

Probably it needs to be spelled out explicitly in documentation.

Changed 9 months ago by timo

comment:2 Changed 9 months ago by timo

  • Has patch set
  • Needs documentation unset
  • Summary changed from Issue with m2m relations when need to prevent saving objects to Document that add() and remove() with a many-to-many relationship do not call Model.save()

comment:3 Changed 9 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from new to closed

In 3cdeb572d73fca3d7966318c760f61ba73e5ad5f:

Fixed #17528 -- Documented that add() and remove() with a many-to-many relationship do not call Model.save()

comment:4 Changed 9 months ago by Tim Graham <timograham@…>

In 61c8c1b6dcd267a7d4777ff3b0a78eaedb9b95d3:

[1.5.x] Fixed #17528 -- Documented that add() and remove() with a many-to-many relationship do not call Model.save()

Backport of 3cdeb572d7 from master

comment:5 Changed 9 months ago by Tim Graham <timograham@…>

In 1c8e539a7723fe2d76b5c5a8b83c8a3da2d9fc39:

[1.6.x] Fixed #17528 -- Documented that add() and remove() with a many-to-many relationship do not call Model.save()

Backport of 3cdeb572d7 from master

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.