#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 , 14 years ago
| Cc: | added |
|---|---|
| Component: | Database layer (models, ORM) → Documentation |
| Needs documentation: | set |
| Triage Stage: | Unreviewed → Accepted |
by , 12 years ago
| Attachment: | 17528.diff added |
|---|
comment:2 by , 12 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 , 12 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.