queryset .all() behavior change in 3.2

90 views
Skip to first unread message

Riccardo Magliocchetti

unread,
Jul 13, 2021, 10:36:55 AM7/13/21
to django-d...@googlegroups.com
Hello,

when porting a django application from 3.1.13 to 3.2.5 I found a behavior change
I don't see documented in the release notes.

The code is cloning a an object and all its related objects by settings the pk
to None. Previously storing a queryset of related objects was enough to being
able to iterate on that even if the original object was cloned, now we have to
make it concrete by calling list() on it.

Code was something like the following:

def clone_object(obj):
related_objs = obj.relatedobj_set.all()
obj.pk = None
obj.save()
for related in related_objs:
related.pk = None
related.object = obj
related.save()

And now the related_object line is as:

related_objs = list(obj.relatedobj_set.all())

Is it something that should be documented in the release notes?

Thanks

--
Riccardo Magliocchetti
@rmistaken

http://menodizero.it

אורי

unread,
Jul 13, 2021, 11:07:40 AM7/13/21
to Django developers (Contributions to Django itself)
Hi Riccardo,

It looks to me that obj.relatedobj_set.all() has to be evaluated before setting obj.pk = None. for and list() causes it to be evaluated. So it's better programming to evaluate it on the lines above setting obj.pk = None. I'm not sure how it is related to Django versions, though.

Uri.


--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/2472148f-0503-65de-c3cd-8a0ad4903011%40gmail.com.

Riccardo Magliocchetti

unread,
Jul 13, 2021, 12:40:25 PM7/13/21
to django-d...@googlegroups.com
Hi Uri,

I'm not arguing that the code was correct :) I'm just reporting a reproducible
change in behavior. The tests did run fine with 2.2 and 3.1 and bumping to 3.2
required a code change.

Thanks

On 13/07/21 17:07, אורי wrote:
> Hi Riccardo,
>
> It looks to me that *obj.relatedobj_set.all()* has to be evaluated before
> setting *obj.pk <http://obj.pk> = None*. *for* and *list()* causes it to be
> evaluated. So it's better programming to evaluate it on the lines above
> setting *obj.pk <http://obj.pk> = None*. I'm not sure how it is related to
Reply all
Reply to author
Forward
0 new messages