[Django] #33276: Strange difference for prefetched_objects between related_field.remove, m2m_related_field.remove and generic_related_field.remove.

7 views
Skip to first unread message

Django

unread,
Nov 9, 2021, 2:34:55 PM11/9/21
to django-...@googlegroups.com
#33276: Strange difference for prefetched_objects between related_field.remove,
m2m_related_field.remove and generic_related_field.remove.
-------------------------------------+-------------------------------------
Reporter: Maxim | Owner: nobody
Danilov |
Type: | Status: new
Cleanup/optimization |
Component: Database | Version: 3.2
layer (models, ORM) |
Severity: Normal | Keywords: prefetch_related
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 1
UI/UX: 0 |
-------------------------------------+-------------------------------------
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.

--
Ticket URL: <https://code.djangoproject.com/ticket/33276>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 10, 2021, 3:23:39 AM11/10/21
to django-...@googlegroups.com
#33276: Strange difference for prefetched_objects between related_field.remove,
m2m_related_field.remove and generic_related_field.remove.
-------------------------------------+-------------------------------------
Reporter: Maxim Danilov | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Database layer | Version: 3.2
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: prefetch_related | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* status: new => closed
* resolution: => wontfix


Comment:

Hi Maxim.

> 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.

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 between `remove()` and `clear()`.
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.

--
Ticket URL: <https://code.djangoproject.com/ticket/33276#comment:1>

Reply all
Reply to author
Forward
0 new messages