diff --git a/django/db/models/manager.py b/django/db/models/manager.py
index e1bbf6e..c32b45e 100644
--- a/django/db/models/manager.py
+++ b/django/db/models/manager.py
@@ -133,6 +133,9 @@ class Manager(object):
     def get_or_create(self, **kwargs):
         return self.get_query_set().get_or_create(**kwargs)
 
+    def update_or_create(self, **kwargs):
+        return self.get_query_set().update_or_create(**kwargs)
+
     def create(self, **kwargs):
         return self.get_query_set().create(**kwargs)
 
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 755820c..1c2dad5 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -469,6 +469,43 @@ class QuerySet(object):
                     # Re-raise the IntegrityError with its original traceback.
                     raise exc_info[1], None, exc_info[2]
 
+    def update_or_create(self, **kwargs):
+        """
+        Looks up an object with the given kwargs, creating one if necessary.
+        If the object already exists, then its fields are updated with the
+        values passed in the defaults dictionary.
+        Returns a tuple of (object, created), where created is a boolean
+        specifying whether an object was created.
+
+        TODO: opportunity for refactoring common code with get_or_create()
+        """
+        assert kwargs, \
+            'update_or_create() must be passed at least one keyword argument'
+        defaults = kwargs.pop('defaults', {})
+        lookup = kwargs.copy()
+        for f in self.model._meta.fields:
+            if f.attname in lookup:
+                lookup[f.name] = lookup.pop(f.attname)
+        self._for_write = True
+        sid = transaction.savepoint(using=self.db)
+        try:
+            obj = self.get(**lookup)
+            create = False
+        except self.model.DoesNotExist:
+            params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
+            obj = self.model(**params)
+            create = True
+        for attname, value in defaults.items():
+            setattr(obj, attname, value)
+        try:
+            obj.save(force_insert=create, using=self.db)
+            transaction.savepoint_commit(sid, using=self.db)
+            return obj, create
+        except IntegrityError:
+            transaction.savepoint_rollback(sid, using=self.db)
+            exc_info = sys.exc_info()
+            raise exc_info[1], None, exc_info[2]
+
     def latest(self, field_name=None):
         """
         Returns the latest object, according to the model's 'get_latest_by'
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index eef2272..dfe04a0 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -1342,6 +1342,55 @@ has a side effect on your data. For more, see `Safe methods`_ in the HTTP spec.
 
 .. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
 
+update_or_create
+~~~~~~~~~~~~~~~~
+
+.. method:: update_or_create(**kwargs)
+
+.. versionadded:: 1.5
+
+A convenience method for looking up an object with the given kwargs, and then
+either updating the values of the object if one is found or creating an
+object if one was not found.
+
+Like ``get_or_create()``, this method returns a tuple of ``(object, created)``,
+where ``object`` is the updated or created object and ``created`` is a boolean
+specifying whether a new object was created.
+
+This is meant as a shortcut to the following type of code::
+
+    obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon',
+                       defaults={'birthday': date(1940, 10, 9)})
+    if not created:
+        obj.update(birthday=date(1940, 10, 9))
+
+This pattern gets quite unwieldy as the number of fields in a model goes up.
+The above example can be rewritten using ``update_or_create()`` like so::
+
+    obj, created = Person.objects.update_or_create(first_name='John', last_name='Lennon',
+                       defaults={'birthday': date(1940, 10, 9)})
+
+Any keyword arguments passed to ``update_or_create()`` — *except* an optional
+one called ``defaults`` — will be used in a :meth:`get()` call. If an object is
+found, ``update_or_create()`` updates values of its fields according to
+``defaults`` and returns a tuple of that object and ``False``. If an object is
+*not* found, ``update_or_create()`` will instantiate and save a new object,
+returning a tuple of the new object and ``True``. The new object will be created
+in a similar way to ``get_or_create()``.
+
+The ``defaults`` parameter should be a dict of attribute-value pairs that
+you want to update. If ``defaults`` is empty or not specified, then
+``update_or_create()`` will act exactly like ``get_or_create()`` since there
+would be nothing to update.
+
+As with ``get_or_create()``, if you need to use ``update_or_create()`` in a
+view, please make sure to use it only in ``POST`` requests unless you have a
+good reason not to. ``GET`` requests shouldn't have any effect on data; use
+``POST`` whenever a request to a page has a side effect on your data. For
+more, see `Safe methods`_ in the HTTP spec.
+
+.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
+
 bulk_create
 ~~~~~~~~~~~
 
diff --git a/tests/modeltests/update_or_create/__init__.py b/tests/modeltests/update_or_create/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/modeltests/update_or_create/models.py b/tests/modeltests/update_or_create/models.py
new file mode 100644
index 0000000..32ac33f
--- /dev/null
+++ b/tests/modeltests/update_or_create/models.py
@@ -0,0 +1,22 @@
+"""
+XX. update_or_create()
+
+``get_or_create()`` does what it says: it tries to look up an object with the
+given parameters. If an object isn't found, it creates one with the given
+parameters. Otherwise it updates the existing object with the given default
+values.
+"""
+
+from django.db import models
+
+class Person(models.Model):
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    birthday = models.DateField()
+
+    def __str__(self):
+        return '%s %s, Birthday: %s' % (self.first_name, self.last_name,
+                                        self.birthday)
+
+    class Meta:
+        ordering = ('last_name',)
diff --git a/tests/modeltests/update_or_create/tests.py b/tests/modeltests/update_or_create/tests.py
new file mode 100644
index 0000000..53c3d33
--- /dev/null
+++ b/tests/modeltests/update_or_create/tests.py
@@ -0,0 +1,55 @@
+from __future__ import absolute_import
+
+from datetime import date
+
+from django.test import TestCase
+
+from .models import Person
+
+
+class UpdateOrCreateTests(TestCase):
+    def test_update_or_create(self):
+        Person.objects.create(
+            first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)
+        )
+
+        p, created = Person.objects.update_or_create(
+            first_name='John', last_name='Lennon', defaults={
+                'birthday': date(1970, 10, 9)
+            }
+        )
+        self.assertFalse(created)
+        self.assertEqual(Person.objects.count(), 1)
+
+        p, created = Person.objects.update_or_create(
+            first_name='George', last_name='Harrison', defaults={
+                'birthday': date(1943, 2, 25)
+            }
+        )
+        self.assertTrue(created)
+        self.assertEqual(Person.objects.count(), 2)
+
+        # If we execute the exact same statement, it won't create a Person.
+        p, created = Person.objects.update_or_create(
+            first_name='George', last_name='Harrison', defaults={
+                'birthday': date(1943, 2, 25)
+            }
+        )
+        self.assertFalse(created)
+        self.assertEqual(Person.objects.count(), 2)
+
+        # update_or_create() can take an empty 'defaults' parameter, but in
+        # this situation behaves exactly like get_or_create().  This is useful
+        # if you are building the 'defaults' dictionary dynamically.
+        p, created = Person.objects.update_or_create(
+            first_name='George', last_name='Harrison', defaults={}
+        )
+        self.assertFalse(created)
+
+        # A different name with an empty 'defaults'.
+        p, created = Person.objects.update_or_create(
+            first_name='John', last_name='Smith', birthday=date(1950, 2, 10),
+            defaults={}
+        )
+        self.assertTrue(created)
+        self.assertEqual(Person.objects.count(), 3)
