Use all the fields to determine _id variants. Fixes #214

If a tracker is defined on an inherited model, where the parent has a ForeignKey,
the tracker will now correctly determine that the field_map takes `fk` -> `fk_id`
This commit is contained in:
Mike Bryant 2016-03-31 15:26:11 +01:00
parent bb04069f01
commit ff3f8e5546
5 changed files with 17 additions and 3 deletions

View file

@ -22,6 +22,7 @@ Jeff Elmore <jeffelmore.org>
Keryn Knight <kerynknight.com>
Matthew Schinckel <matt@schinckel.net>
Michael van Tellingen <michaelvantellingen@gmail.com>
Mike Bryant <mike@mikebryant.me.uk>
Mikhail Silonov <silonov.pro>
Patryk Zawadzki <patrys@room-303.com>
Paul McLanahan <paul@mclanahan.net>

View file

@ -8,6 +8,9 @@ master (unreleased)
* Add support for Django 1.10.
* Track foreign keys on parent models properly when a tracker
is defined on a child model. Fixes GH-214.
2.4 (2015-12-03)
----------------

View file

@ -246,6 +246,11 @@ class InheritedTracked(Tracked):
name2 = models.CharField(max_length=20)
class InheritedTrackedFK(TrackedFK):
custom_tracker = FieldTracker(fields=['fk_id'])
custom_tracker_without_id = FieldTracker(fields=['fk'])
class ModelTracked(models.Model):
name = models.CharField(max_length=20)
number = models.IntegerField()

View file

@ -26,7 +26,7 @@ from model_utils.tests.models import (
StatusPlainTuple, TimeFrame, Monitored, MonitorWhen, MonitorWhenEmpty, StatusManagerAdded,
TimeFrameManagerAdded, SplitFieldAbstractParent,
ModelTracked, ModelTrackedFK, ModelTrackedNotDefault, ModelTrackedMultiple, InheritedModelTracked,
Tracked, TrackedFK, TrackedNotDefault, TrackedNonFieldAttr, TrackedMultiple,
Tracked, TrackedFK, InheritedTrackedFK, TrackedNotDefault, TrackedNonFieldAttr, TrackedMultiple,
InheritedTracked, StatusFieldDefaultFilled, StatusFieldDefaultNotFilled,
InheritanceManagerTestChild3, StatusFieldChoicesName)
@ -1682,6 +1682,11 @@ class InheritedFieldTrackerTests(FieldTrackerTests):
self.assertRaises(FieldError, self.tracker.has_changed, 'name2')
class FieldTrackerInheritedForeignKeyTests(FieldTrackerForeignKeyTests):
tracked_class = InheritedTrackedFK
class ModelTrackerTests(FieldTrackerTests):
tracked_class = ModelTracked

View file

@ -101,7 +101,7 @@ class FieldTracker(object):
def get_field_map(self, cls):
"""Returns dict mapping fields names to model attribute names"""
field_map = dict((field, field) for field in self.fields)
all_fields = dict((f.name, f.attname) for f in cls._meta.local_fields)
all_fields = dict((f.name, f.attname) for f in cls._meta.fields)
field_map.update(**dict((k, v) for (k, v) in all_fields.items()
if k in field_map))
return field_map
@ -113,7 +113,7 @@ class FieldTracker(object):
def finalize_class(self, sender, **kwargs):
if self.fields is None:
self.fields = (field.attname for field in sender._meta.local_fields)
self.fields = (field.attname for field in sender._meta.fields)
self.fields = set(self.fields)
self.field_map = self.get_field_map(sender)
models.signals.post_init.connect(self.initialize_tracker)