fix #330 patch MyModel.save instead of MyModel().save

This commit is contained in:
tumb1er 2018-11-20 17:49:52 +03:00
parent 05671695bb
commit ba83be0b43
4 changed files with 24 additions and 7 deletions

View file

@ -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)
------------------

View file

@ -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:

View file

@ -8,3 +8,9 @@ DATABASES = {
}
}
SECRET_KEY = 'dummy'
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}

View file

@ -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'