mirror of
https://github.com/Hopiu/django-model-utils.git
synced 2026-03-16 20:00:23 +00:00
Catch deferred attribute exception (#367)
This commit is contained in:
parent
c4a252d1fb
commit
d557c42533
4 changed files with 27 additions and 3 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue