Opened 3 years ago
Closed 3 years ago
#33276 closed Cleanup/optimization (wontfix)
Strange difference for prefetched_objects between related_field.remove, m2m_related_field.remove and generic_related_field.remove.
Reported by: | Maxim Danilov | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.2 |
Severity: | Normal | Keywords: | prefetch_related |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
Hello.
i want to call _remove_prefetched_objects only to remove cached old data. But i dont want to use private method.
instance.m2m_related_field.remove() - made what i want.
instance.generic_related_field.remove() - Does nothing
instance.related_field.remove() - Does nothing
in django (> 3.2) code i see:
# (django.db.models.fields.related_descriptors 964-965) # m2m_related_field def remove(self, *objs): self._remove_prefetched_objects() ... # (django.contrib.contenttypes.fields 635-645) # generic_related_field def remove(self, *objs, bulk=True): if not objs: return ... return self._clear(...) def _clear(...): self._remove_prefetched_objects() # (django.db.models.fields.related_descriptors 694-719) # related_field def remove(self, *objs, bulk=True): if not objs: return .... return self_clear(...) def _clear(...): self._remove_prefetched_objects()
i think, It is better to made the same functionality in remove method for all related fields.
# for all related fields: def remove(self, *objs): self._remove_prefetched_objects() if objs: return self._do_something_to_remove(....)
This made a removal interface more standard.
Note:
See TracTickets
for help on using tickets.
Hi Maxim.
This doesn't sound right. 🤔
remove()
will (erm) remove the objects from the M2M relation, not just remove cached old data — it alters the data in the DB.If you just want to remove the prefetch cache I think you'll need to use the private method, or call
refresh_from_db()
, or similar.The
_clear()
method is a shared helper betweenremove()
andclear()
. Moving the_remove_prefetched_objects()
to the public methods will just cause duplication of the implementation there. I don't think that's a change we want to make.Thanks.