Index: django/db/models/base.py
===================================================================
--- django/db/models/base.py	(revision 7543)
+++ django/db/models/base.py	(working copy)
@@ -165,11 +165,21 @@
 class Model(object):
     __metaclass__ = ModelBase
 
+    def __setattr__(self, name, value):
+        if name not in self._modified_attrs:
+            if not hasattr(self, name) or value != getattr(self, name):
+                self._modified_attrs.append(name)
+        super(Model, self).__setattr__(name, value)
+
+    def _reset_modified_attrs(self):
+        self.__dict__['_modified_attrs'] = []
+
     def __init__(self, *args, **kwargs):
+        self._reset_modified_attrs()
         dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs)
 
         # There is a rather weird disparity here; if kwargs, it's set, then args
-        # overrides it. It should be one or the other; don't duplicate the work
+        # overrides it. It should be one or the other; don't duplicate the work.
         # The reason for the kwargs check is that standard iterator passes in by
         # args, and instantiation for iteration is 33% faster.
         args_len = len(args)
@@ -295,6 +305,9 @@
             setattr(self, field.attname, self._get_pk_val(parent._meta))
 
         non_pks = [f for f in meta.local_fields if not f.primary_key]
+        modified_attrs = self._modified_attrs
+        non_pks = [f for f in non_pks if (f.name in modified_attrs or f.attname in modified_attrs)]
+        self._reset_modified_attrs()
 
         # First, try an UPDATE. If that doesn't update anything, do an INSERT.
         pk_val = self._get_pk_val(meta)
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revision 7543)
+++ django/db/models/query.py	(working copy)
@@ -165,6 +165,10 @@
                         max_depth, requested=requested)
             else:
                 obj = self.model(*row[index_start:])
+                # Models keep a track of modified attrs to choose which
+                # fields to save. Since we're just pulling from the
+                # database, nothing has changed yet.
+                obj._reset_modified_attrs()
             for i, k in enumerate(extra_select):
                 setattr(obj, k, row[i])
             yield obj
Index: tests/modeltests/update_fields/__init__.py
===================================================================
Index: tests/modeltests/update_fields/models.py
===================================================================
--- tests/modeltests/update_fields/models.py	(revision 0)
+++ tests/modeltests/update_fields/models.py	(revision 0)
@@ -0,0 +1,122 @@
+"""
+#. Save only modified fields on update
+"""
+from django.db import models
+
+class Article(models.Model):
+    headline = models.CharField(maxlength=100, default='Default headline')
+    body = models.TextField()
+    pub_date = models.DateTimeField()
+
+    class Meta:
+        ordering = ('pub_date','headline')
+
+    def __str__(self):
+        return self.headline
+
+__test__ = {'API_TESTS':"""
+# Create a couple of Articles.
+>>> from datetime import datetime
+>>> a = Article(headline='Article 1', body='Body 1', pub_date=datetime(2007, 5, 5))
+>>> a.save()
+
+# Change headline and body on different instances, then save both to verify
+# that each only updated the modified field.
+>>> a1 = Article.objects.get(pk=a.id)
+>>> a2 = Article.objects.get(pk=a.id)
+>>> a1.headline = 'Changed article 1'
+>>> a2.body = 'Changed body 1'
+>>> a1.save()
+>>> a2.save()
+>>> a3 = Article.objects.get(pk=a.id)
+>>> a3.headline
+u'Changed article 1'
+>>> a3.body
+u'Changed body 1'
+
+# Fields entered at instantiation of a model which will already exists should be
+# saved as well.
+>>> a = Article(id=a.id, headline='Reset article 1', body='Reset body 1', pub_date=datetime(2007, 5, 5))
+>>> a.save()
+>>> a3 = Article.objects.get(pk=a.id)
+>>> a3.headline
+u'Reset article 1'
+>>> a3.body
+u'Reset body 1'
+
+# If the value doesn't change, it won't be marked as modified -- otherwise user
+# input like forms/etc is going to mark everything modified regardless.
+>>> a1 = Article.objects.get(pk=a.id)
+>>> a2 = Article.objects.get(pk=a.id)
+>>> a1.headline = 'Changed article 2'
+>>> a2.headline = a2.headline
+>>> a2.body = 'Changed body 2'
+>>> a1.save()
+>>> a2.save()
+>>> a3 = Article.objects.get(pk=a.id)
+>>> a3.headline
+u'Changed article 2'
+>>> a3.body
+u'Changed body 2'
+"""}
+"""
+#. Save only modified fields on update
+"""
+from django.db import models
+
+class Article(models.Model):
+    headline = models.CharField(maxlength=100, default='Default headline')
+    body = models.TextField()
+    pub_date = models.DateTimeField()
+
+    class Meta:
+        ordering = ('pub_date','headline')
+
+    def __str__(self):
+        return self.headline
+
+__test__ = {'API_TESTS':"""
+# Create a couple of Articles.
+>>> from datetime import datetime
+>>> a = Article(headline='Article 1', body='Body 1', pub_date=datetime(2007, 5, 5))
+>>> a.save()
+
+# Change headline and body on different instances, then save both to verify
+# that each only updated the modified field.
+>>> a1 = Article.objects.get(pk=a.id)
+>>> a2 = Article.objects.get(pk=a.id)
+>>> a1.headline = 'Changed article 1'
+>>> a2.body = 'Changed body 1'
+>>> a1.save()
+>>> a2.save()
+>>> a3 = Article.objects.get(pk=a.id)
+>>> a3.headline
+u'Changed article 1'
+>>> a3.body
+u'Changed body 1'
+
+# Fields entered at instantiation of a model which will already exists should be
+# saved as well.
+>>> a = Article(id=a.id, headline='Reset article 1', body='Reset body 1', pub_date=datetime(2007, 5, 5))
+>>> a.save()
+>>> a3 = Article.objects.get(pk=a.id)
+>>> a3.headline
+u'Reset article 1'
+>>> a3.body
+u'Reset body 1'
+
+# If the value doesn't change, it won't be marked as modified -- otherwise user
+# input like forms/etc is going to mark everything modified regardless.
+>>> a1 = Article.objects.get(pk=a.id)
+>>> a2 = Article.objects.get(pk=a.id)
+>>> a1.headline = 'Changed article 2'
+>>> a2.headline = a2.headline
+>>> a2.body = 'Changed body 2'
+>>> a1.save()
+>>> a2.save()
+>>> a3 = Article.objects.get(pk=a.id)
+>>> a3.headline
+u'Changed article 2'
+>>> a3.body
+u'Changed body 2'
+"""}
