﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
34925	refresh_from_db() will not iterate through all of the fields listed in the 'fields' parameter.	Andrew Cordery	Trontelj	"This one was killing me today.  If you pass the 'fields' parameter to {{{refresh_from_db}}} it is supposed to only remove those fields from {{{_prefetched_objects_cache}}} as described in the docs: https://docs.djangoproject.com/en/4.2/ref/models/instances/#django.db.models.Model.refresh_from_db.

Unfortunately, it modifies the 'fields' variable as it iterates through it:

''Line 694 of django.db.models.base.py:''
{{{
            for field in fields:
                if field in prefetched_objects_cache:
                    del prefetched_objects_cache[field]
                    fields.remove(field)
}}}

Modifying the list that we are iterating over causes some list items to be skipped.  For example here we would expected to see 'a', 'b', and 'c', removed from dict {{{d}}} but 'b' is skipped: 

{{{
In [8]: d = dict(a=1,b=2, c=3)

In [9]: fields = ['a','b','c']

In [10]: for f in fields:
    ...:     print(f)
    ...:     if f in d:
    ...:         del d[f]
    ...:         fields.remove(f)
    ...: 
a
c

In [11]: fields
Out[11]: ['b']
In [12]: d
Out[12]: {'b': 2}

}}}

I beieve that all that needs to be done to correct this is to create a copy of the list by wrapping fields in list(), like so:

{{{
In [13]: fields = ['a','b','c']

In [14]: d=dict(a=1,b=2, c=3)

In [15]: for f in list(fields):
    ...:     print(f)
    ...:     if f in d:
    ...:         del d[f]
    ...:         fields.remove(f)
    ...: 
a
b
c

In [16]: d
Out[16]: {}

In [17]: fields
Out[17]: []
}}}

Therefore as far as I can tell the fix to the django code would be as easy as wrapping fields in list():

''Line 694 of django.db.models.base.py:'' modified
{{{
            for field in list(fields):
                if field in prefetched_objects_cache:
                    del prefetched_objects_cache[field]
                    fields.remove(field)
}}}"	Bug	closed	Database layer (models, ORM)	5.0	Normal	fixed			Ready for checkin	1	0	0	0	1	0
