diff --git a/djblets/db/fields/modification_timestamp_field.py b/djblets/db/fields/modification_timestamp_field.py
index 4169a04c1ecb19b8e14f70b42c958bf099377591..786fdad6484cdc6c012fde18fe8d0ef174dbee57 100644
--- a/djblets/db/fields/modification_timestamp_field.py
+++ b/djblets/db/fields/modification_timestamp_field.py
@@ -6,6 +6,105 @@ from django.db import models
 from django.utils import timezone
 
 
+class ModificationState(object):
+    """Modification state for a tracked value.
+
+    Attributes:
+        first_set (bool):
+            Whether or not the next :py:func:`setattr` will be the first.
+
+            When this is ``True``, we do not consider the next
+            :py:func:`setattr` to be a modification since the field will be
+            set during model initialization.
+
+        modified (bool):
+            Whether or not the value has been manually modified.
+    """
+
+    def __init__(self):
+        """Initialize the state."""
+        self.modified = False
+        self.first_set = False
+
+    @staticmethod
+    def get_attr_name(field_name):
+        """Return the attribute name for the state for the named field.
+
+        Args:
+            field_name (unicode):
+                The attribute name of the
+                :py:class:`ModificationTimestampField`.
+
+        Returns:
+            unicode:
+            The name of the modification state attribute.
+        """
+        return '_%s_state' % field_name
+
+
+class ModificationTrackedValue(object):
+    """A descriptor for tracking the modification of a value.
+
+    Attributes:
+        field_name (unicode):
+            The attribute name of the field on the model.
+
+        state_name (unicode):
+            The attribute name of the state on the model.
+    """
+
+    def __init__(self, field_name, state_name):
+        """Initialize the descriptor.
+
+        Args:
+            field_name (unicode):
+                The name of the field attribute.
+
+            state_name (unicode):
+                The name of the state attribute.
+        """
+        self.field_name = field_name
+        self.state_name = state_name
+
+    def __get__(self, instance, objtype=None):
+        """Return the value.
+
+        Args:
+            instance (django.db.models.Model):
+                The model instance.
+
+            objtype (type, optional):
+                The model class.
+
+        Returns:
+            datetime.datetime:
+            The value.
+        """
+        return instance.__dict__[self.field_name]
+
+    def __set__(self, instance, value):
+        """Set the value.
+
+        This tracks modifications and updates the state if this is not the
+        first call to this method (which occurs during model initialization).
+
+        Args:
+            instance (django.db.models.Model):
+                The instance to set the the value on.
+
+            value (datetime.datetime):
+                The value to set.state.first_set:
+        """
+        state = getattr(instance, self.state_name)
+
+        if state.first_set:
+            state.first_set = False
+        else:
+            state.modified = True
+
+        instance.__dict__[self.field_name] = value
+
+
 class ModificationTimestampField(models.DateTimeField):
     """A timestamp field that only updates existing objects or when None.
 
@@ -31,6 +130,23 @@ class ModificationTimestampField(models.DateTimeField):
         })
         super(ModificationTimestampField, self).__init__(*args, **kwargs)
 
+    def contribute_to_class(self, cls, name):
+        """Contribute the field attributes to the class.
+
+        Args:
+            cls (type):
+                The model class to contribute the field to.
+
+            name (unicode):
+                The name of the field.
+        """
+        super(ModificationTimestampField, self).contribute_to_class(cls, name)
+
+        state_name = ModificationState.get_attr_name(self.name)
+        setattr(cls, self.name,
+                ModificationTrackedValue(self.name, state_name))
+        setattr(cls, state_name, ModificationState())
+
     def pre_save(self, model_instance, add):
         """Return the value of the field just before saving.
 
@@ -45,11 +161,18 @@ class ModificationTimestampField(models.DateTimeField):
             datetime.datetime:
             The date/time value being saved.
         """
-        if not add or self.value_from_object(model_instance) is None:
+        state = getattr(model_instance,
+                        ModificationState.get_attr_name(self.name))
+        existing_value = getattr(model_instance, self.attname)
+
+        if ((not add and not state.modified) or
+            (add and existing_value is None)):
             value = timezone.now()
             setattr(model_instance, self.attname, value)
-        else:
+        elif ((not add and state.modified) or
+              (add and existing_value is not None)):
             value = super(ModificationTimestampField, self).pre_save(
                 model_instance, add)
 
+        state.modified = False
         return value
diff --git a/djblets/db/tests/test_modification_timestamp_field.py b/djblets/db/tests/test_modification_timestamp_field.py
index 56cd0e8f14239423a1260078e157582137817d67..aad5a412697cd347b0d0251c9ef4998ac751c5f2 100644
--- a/djblets/db/tests/test_modification_timestamp_field.py
+++ b/djblets/db/tests/test_modification_timestamp_field.py
@@ -2,10 +2,11 @@
 
 from __future__ import unicode_literals
 
-from datetime import datetime
+from datetime import datetime, timedelta
 
 from django.db import models
 from django.utils import timezone
+from kgb import SpyAgency
 
 from djblets.db.fields.modification_timestamp_field import \
     ModificationTimestampField
@@ -16,7 +17,13 @@ class ModificationTimestampFieldTestModel(models.Model):
     field = ModificationTimestampField()
 
 
-class ModificationTimestampFieldTests(TestModelsLoaderMixin, TestCase):
+class MultitipleModificationTimestampFieldTestModel(models.Model):
+    timestamp1 = ModificationTimestampField('timestamp1')
+    timestamp2 = ModificationTimestampField('timestamp2')
+
+
+class ModificationTimestampFieldTests(SpyAgency, TestModelsLoaderMixin,
+                                      TestCase):
     """Unit tests for ModificationTimestampField."""
 
     tests_app = 'djblets.db.tests'
@@ -63,3 +70,119 @@ class ModificationTimestampFieldTests(TestModelsLoaderMixin, TestCase):
         obj = ModificationTimestampFieldTestModel()
         self.assertEqual(obj._meta.get_field('field').get_internal_type(),
                          'DateTimeField')
+
+    def test_save_updates_value_with_tz(self):
+        """Testing ModificationTimestampField updates the value on save when
+        USE_TZ=True
+        """
+        with self.settings(USE_TZ=True):
+            original_timestamp = timestamp = timezone.now()
+            self.spy_on(timezone.now, call_fake=lambda: timestamp)
+
+            instance = ModificationTimestampFieldTestModel.objects.create()
+            self.assertEqual(instance.field, timestamp)
+
+            timestamp += timedelta(hours=1)
+            instance.save()
+            self.assertEqual(instance.field, timestamp)
+            self.assertNotEqual(instance.field, original_timestamp)
+
+    def test_save_updates_value_without_tz(self):
+        """Testing ModificationTimestampField udpates the value on save when
+        USE_TZ=False
+        """
+        with self.settings(USE_TZ=False):
+            original_timestamp = timestamp = timezone.now()
+            self.spy_on(timezone.now, call_fake=lambda: timestamp)
+
+            instance = ModificationTimestampFieldTestModel.objects.create()
+            self.assertEqual(instance.field, timestamp)
+
+            timestamp += timedelta(hours=1)
+            instance.save()
+            self.assertEqual(instance.field, timestamp)
+            self.assertNotEqual(instance.field, original_timestamp)
+
+    def test_save_doesnt_overwrite_modified_value_with_tz(self):
+        """Testing ModificationTimestampField doesn't overwite manual setting
+        of the field when USE_TZ=False
+        """
+        with self.settings(USE_TZ=True):
+            timestamp = timezone.now()
+            self.spy_on(timezone.now, call_fake=lambda: timestamp)
+
+            instance = ModificationTimestampFieldTestModel.objects.create()
+            instance.field += timedelta(hours=1)
+            instance.save()
+
+            self.assertNotEqual(instance.field, timestamp)
+            self.assertEqual(instance.field,
+                             timestamp + timedelta(hours=1))
+
+    def test_save_doesnt_overwite_modified_value_without_tz(self):
+        """Testing ModificationTimestampField doesn't overwite manual setting
+        of the field when USE_TZ=False
+        """
+        with self.settings(USE_TZ=False):
+            timestamp = timezone.now()
+            self.spy_on(timezone.now, call_fake=lambda: timestamp)
+
+            instance = ModificationTimestampFieldTestModel.objects.create()
+            instance.field += timedelta(hours=1)
+            instance.save()
+
+            self.assertNotEqual(instance.field, timestamp)
+            self.assertEqual(instance.field,
+                             timestamp + timedelta(hours=1))
+
+    def test_save_multiple_with_tz(self):
+        """Testing multiple ModificationTimestampField save correctly when
+        USE_TZ=True
+        """
+        with self.settings(USE_TZ=True):
+            timestamp = timezone.now()
+            self.spy_on(timezone.now, call_fake=lambda: timestamp)
+
+            manual_value = timestamp + timedelta(hours=4)
+            timestamp += timedelta(hours=1)
+
+            instance = MultitipleModificationTimestampFieldTestModel()
+            instance.timestamp1 = manual_value
+            instance.save()
+
+            self.assertEqual(instance.timestamp1, manual_value)
+            self.assertEqual(instance.timestamp2, timestamp)
+
+            timestamp += timedelta(hours=1)
+
+            instance.timestamp2 = manual_value
+            instance.save()
+
+            self.assertEqual(instance.timestamp1, timestamp)
+            self.assertEqual(instance.timestamp2, manual_value)
+
+    def test_save_multiple_without_tz(self):
+        """Testing multiple ModificationTimestampField save correctly when
+        USE_TZ=False
+        """
+        with self.settings(USE_TZ=False):
+            timestamp = timezone.now()
+            self.spy_on(timezone.now, call_fake=lambda: timestamp)
+
+            manual_value = timestamp + timedelta(hours=4)
+            timestamp += timedelta(hours=1)
+
+            instance = MultitipleModificationTimestampFieldTestModel()
+            instance.timestamp1 = manual_value
+            instance.save()
+
+            self.assertEqual(instance.timestamp1, manual_value)
+            self.assertEqual(instance.timestamp2, timestamp)
+
+            timestamp += timedelta(hours=1)
+
+            instance.timestamp2 = manual_value
+            instance.save()
+
+            self.assertEqual(instance.timestamp1, timestamp)
+            self.assertEqual(instance.timestamp2, manual_value)
