diff --git a/CHANGES.rst b/CHANGES.rst index 85cf4cb..7d71665 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,7 @@ master (unreleased) - Fix handling of deferred attributes on Django 1.10+, fixes GH-278 - Fix `FieldTracker.has_changed()` and `FieldTracker.previous()` to return correct responses for deferred fields. +- Fix Model instance non picklable GH-330 3.1.2 (2018.05.09) ------------------ diff --git a/model_utils/tracker.py b/model_utils/tracker.py index 8ce10dc..0059224 100644 --- a/model_utils/tracker.py +++ b/model_utils/tracker.py @@ -207,6 +207,7 @@ class FieldTracker(object): def contribute_to_class(self, cls, name): self.name = name self.attname = '_%s' % name + self.patch_save(cls) models.signals.class_prepared.connect(self.finalize_class, sender=cls) def finalize_class(self, sender, **kwargs): @@ -230,14 +231,13 @@ class FieldTracker(object): tracker = self.tracker_class(instance, self.fields, self.field_map) setattr(instance, self.attname, tracker) tracker.set_saved_fields() - self.patch_save(instance) instance._instance_intialized = True - def patch_save(self, instance): - original_save = instance.save + def patch_save(self, model): + original_save = model.save - def save(**kwargs): - ret = original_save(**kwargs) + def save(instance, **kwargs): + ret = original_save(instance, **kwargs) update_fields = kwargs.get('update_fields') if not update_fields and update_fields is not None: # () or [] fields = update_fields @@ -253,7 +253,7 @@ class FieldTracker(object): ) return ret - instance.save = save + model.save = save def __get__(self, instance, owner): if instance is None: diff --git a/tests/settings.py b/tests/settings.py index 8817e83..b3be03a 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -8,3 +8,9 @@ DATABASES = { } } SECRET_KEY = 'dummy' + +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + } +} diff --git a/tests/test_fields/test_field_tracker.py b/tests/test_fields/test_field_tracker.py index 43f12f5..65a2bfe 100644 --- a/tests/test_fields/test_field_tracker.py +++ b/tests/test_fields/test_field_tracker.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import django from django.core.exceptions import FieldError from django.test import TestCase - +from django.core.cache import cache from model_utils import FieldTracker from model_utils.tracker import DescriptorWrapper from tests.models import ( @@ -639,6 +639,16 @@ class ModelTrackerTests(FieldTrackerTests): tracked_class = ModelTracked + def test_cache_compatible(self): + cache.set('key', self.instance) + instance = cache.get('key') + instance.number = 1 + instance.name = 'cached' + instance.save() + self.assertChanged() + instance.number = 2 + self.assertHasChanged(number=True) + def test_pre_save_changed(self): self.assertChanged() self.instance.name = 'new age'