Opened 4 years ago
Closed 4 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.