Catch deferred attribute exception (#367)

This commit is contained in:
Nick Sandford 2019-03-29 17:46:40 +11:00 committed by Asif Saif Uddin
parent c4a252d1fb
commit d557c42533
4 changed files with 27 additions and 3 deletions

View file

@ -3,6 +3,7 @@ CHANGES
master (unreleased)
-------------------
- Catch `AttributeError` for deferred abstract fields, fixes GH-331.
- Update documentation to explain usage of `timeframed` model manager, fixes GH-118
- Honor `OneToOneField.parent_link=False`.
- Fix handling of deferred attributes on Django 1.10+, fixes GH-278
@ -14,7 +15,7 @@ master (unreleased)
- Support `reversed` for all kinds of `Choices` objects, fixes GH-309
- Fix Model instance non picklable GH-330
- Fix patched `save` in FieldTracker
- Upgrades test requirements (pytest, pytest-django, pytest-cov) and
- Upgrades test requirements (pytest, pytest-django, pytest-cov) and
skips tox test with Python 3.5 and Django (trunk)
3.1.2 (2018.05.09)

View file

@ -40,7 +40,10 @@ class DescriptorWrapper(object):
if instance is None:
return self
was_deferred = self.field_name in instance.get_deferred_fields()
value = self.descriptor.__get__(instance, owner)
try:
value = self.descriptor.__get__(instance, owner)
except AttributeError:
value = self.descriptor
if was_deferred:
tracker_instance = getattr(instance, self.tracker_attname)
tracker_instance.saved_data[self.field_name] = deepcopy(value)

View file

@ -224,6 +224,13 @@ class FeaturedManager(models.Manager):
return ByAuthorQuerySet(self.model, **kwargs).filter(feature=True)
class AbstractTracked(models.Model):
number = 1
class Meta:
abstract = True
class Tracked(models.Model):
name = models.CharField(max_length=20)
number = models.IntegerField()
@ -240,6 +247,14 @@ class TrackedFK(models.Model):
custom_tracker_without_id = FieldTracker(fields=['fk'])
class TrackedAbstract(AbstractTracked):
name = models.CharField(max_length=20)
number = models.IntegerField()
mutable = MutableField(default=None)
tracker = FieldTracker()
class TrackedNotDefault(models.Model):
name = models.CharField(max_length=20)
number = models.IntegerField()

View file

@ -8,7 +8,7 @@ from model_utils import FieldTracker
from model_utils.tracker import DescriptorWrapper
from tests.models import (
Tracked, TrackedFK, InheritedTrackedFK, TrackedNotDefault, TrackedNonFieldAttr, TrackedMultiple,
InheritedTracked, TrackedFileField,
InheritedTracked, TrackedFileField, TrackedAbstract,
ModelTracked, ModelTrackedFK, ModelTrackedNotDefault, ModelTrackedMultiple, InheritedModelTracked,
)
@ -785,3 +785,8 @@ class InheritedModelTrackerTests(ModelTrackerTests):
self.name2 = 'test'
self.assertEqual(self.tracker.previous('name2'), None)
self.assertTrue(self.tracker.has_changed('name2'))
class AbstractModelTrackerTests(FieldTrackerTestCase):
tracked_class = TrackedAbstract