﻿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
31863	FK field caching behavior change between 1.11.x and 2.x	Gert Burger	Gert Burger	"Whilst upgrading a codebase from 1.11.x to 2.0/2.2 I noticed a weird change in behavior of FK fields when copying model instances.

At the bottom of the post there is a testcase that succeeds on 1.11.x and fails on 2.x
I think the commit that changed the behavior is bfb746f983aa741afa3709794e70f1e0ab6040b5

So my question is two fold:
* Is the behavior in >=2.0 correct? It seems quite unexpected.
* What is the recommended way to clone a model instance? To date we have been using copy() in a similar fashion to the test without issue. deepcopy seems to work fine in >=2.0 but we haven’t done too much testing yet.

Test (placed in tests/model_fields/test_field_caching_change.py):

{{{#!python

import copy
from django.test import TestCase

from .models import Bar, Foo


class ForeignKeyCachingBehaviorTest(TestCase):
    def test_copy(self):
        foo1 = Foo.objects.create(a='foo1', d=1)
        foo2 = Foo.objects.create(a='foo2', d=2)
        bar1 = Bar.objects.create(a=foo1, b='bar1')

        bar2 = copy.copy(bar1)

        bar2.pk = None
        bar2.a = foo2

        # bar2 points to foo2
        self.assertEqual(bar2.a, foo2)
        self.assertEqual(bar2.a.id, bar2.a_id)

        # bar1 is unchanged and must still point to foo1
        # These fail on Django >= 2.0
        self.assertEqual(bar1.a, foo1)
        self.assertEqual(bar1.a.id, bar1.a_id)

}}}

and executed that via:

python3.6 tests/runtests.py --parallel 1 model_fields



In https://groups.google.com/g/django-developers/c/QMhVPIqVVP4/m/mbezfaBEAwAJ Simon suggests:
> ..... Model.__copy__ should make sure to make a deep-copy of self._state now that fields are cached in self._state.fields_cache.

which I will attempt to implement."	Bug	closed	Database layer (models, ORM)	2.2	Normal	fixed			Ready for checkin	1	0	0	0	0	0
