#17528 closed Cleanup/optimization (fixed)
Document that add() and remove() with a many-to-many relationship do not call Model.save()
Reported by: | 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)
Change History (6)
comment:1 by , 13 years ago
Cc: | added |
---|---|
Component: | Database layer (models, ORM) → Documentation |
Needs documentation: | set |
Triage Stage: | Unreviewed → Accepted |
by , 11 years ago
Attachment: | 17528.diff added |
---|
comment:2 by , 11 years ago
Has patch: | set |
---|---|
Needs documentation: | unset |
Summary: | Issue with m2m relations when need to prevent saving objects → Document that add() and remove() with a many-to-many relationship do not call Model.save() |
comment:3 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
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.