Merge pull request #242 from romgar/ticket_241_double_monitor_field_recursion_error

Tests to demonstrate recursion error with double MonitorField and defer()/only() usage
This commit is contained in:
Carl Meyer 2016-11-21 11:13:31 -08:00 committed by GitHub
commit 94870b2510
3 changed files with 32 additions and 1 deletions

View file

@ -110,6 +110,9 @@ class MonitorField(models.DateTimeField):
return getattr(instance, self.monitor)
def _save_initial(self, sender, instance, **kwargs):
if django.VERSION >= (1, 10) and self.monitor in instance.get_deferred_fields():
# Fix related to issue #241 to avoid recursive error on double monitor fields
return
setattr(instance, self.monitor_attname,
self.get_monitored_value(instance))

View file

@ -105,6 +105,12 @@ class MonitorWhenEmpty(models.Model):
name_changed = MonitorField(monitor="name", when=[])
class DoubleMonitored(models.Model):
name = models.CharField(max_length=25)
name_changed = MonitorField(monitor="name")
name2 = models.CharField(max_length=25)
name_changed2 = MonitorField(monitor="name2")
class Status(StatusModel):
STATUS = Choices(

View file

@ -2,6 +2,8 @@ from __future__ import unicode_literals
from datetime import datetime, timedelta
from freezegun import freeze_time
try:
from unittest import skipUnless
except ImportError: # Python 2.6
@ -33,7 +35,7 @@ from model_utils.tests.models import (
Tracked, TrackedFK, InheritedTrackedFK, TrackedNotDefault, TrackedNonFieldAttr, TrackedMultiple,
InheritedTracked, TrackedFileField, StatusFieldDefaultFilled, StatusFieldDefaultNotFilled,
InheritanceManagerTestChild3, StatusFieldChoicesName,
SoftDeletable)
SoftDeletable, DoubleMonitored)
class MigrationsTests(TestCase):
@ -255,6 +257,26 @@ class MonitorWhenEmptyFieldTests(TestCase):
self.assertEqual(self.instance.name_changed, self.created)
class MonitorDoubleFieldTests(TestCase):
def setUp(self):
DoubleMonitored.objects.create(name='Charlie', name2='Charlie2')
def test_recursion_error_with_only(self):
# Any field passed to only() is generating a recursion error
list(DoubleMonitored.objects.only('id'))
def test_recursion_error_with_defer(self):
# Only monitored fields passed to defer() are failing
list(DoubleMonitored.objects.defer('name'))
def test_monitor_still_works_with_deferred_fields_filtered_out_of_save_initial(self):
obj = DoubleMonitored.objects.defer('name').get(name='Charlie')
with freeze_time("2016-12-01"):
obj.name = 'Charlie2'
obj.save()
self.assertEqual(obj.name_changed, datetime(2016, 12, 1))
class StatusFieldTests(TestCase):