=== modified file 'django/db/models/base.py'
--- django/db/models/base.py	2009-03-15 03:41:33 +0000
+++ django/db/models/base.py	2009-03-15 16:32:50 +0000
@@ -331,6 +331,18 @@
 
     save.alters_data = True
 
+    def update(self, **kwargs):
+        """
+        Set the object's fields to the new values passed in as keyword
+        arguments and then save the object.  Fields not specified in the
+        keyword arguments will not be altered.
+        """
+        for k, v in kwargs.iteritems():
+            setattr(self, k, v)
+        self.save()
+
+    update.alters_data = True
+
     def save_base(self, raw=False, cls=None, force_insert=False,
             force_update=False):
         """

=== modified file 'django/db/models/manager.py'
--- django/db/models/manager.py	2009-03-15 03:41:33 +0000
+++ django/db/models/manager.py	2009-03-15 16:09:08 +0000
@@ -119,6 +119,9 @@
     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)
 

=== modified file 'django/db/models/query.py'
--- django/db/models/query.py	2009-03-11 07:06:50 +0000
+++ django/db/models/query.py	2009-03-15 16:09:08 +0000
@@ -379,6 +379,19 @@
                 except self.model.DoesNotExist:
                     raise e
 
+    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.
+        """
+        obj, created = self.get_or_create(**kwargs)
+        if not created:
+            obj.update(**kwargs.pop('defaults', {}))
+        return obj, created
+
     def latest(self, field_name=None):
         """
         Returns the latest object, according to the model's 'get_latest_by'

=== modified file 'docs/ref/models/instances.txt'
--- docs/ref/models/instances.txt	2008-10-06 08:28:18 +0000
+++ docs/ref/models/instances.txt	2009-03-15 16:57:38 +0000
@@ -5,7 +5,7 @@
 ========================
 
 .. currentmodule:: django.db.models
-   
+
 This document describes the details of the ``Model`` API. It builds on the
 material presented in the :ref:`model <topics-db-models>` and :ref:`database
 query <topics-db-queries>` guides, so you'll probably want to read and
@@ -49,7 +49,7 @@
 your object the first time you call ``save()``::
 
     >>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
-    >>> b2.id     # Returns None, because b doesn't have an ID yet.
+    >>> b2.id     # Returns None, because b2 doesn't have an ID yet.
     >>> b2.save()
     >>> b2.id     # Returns the ID of your new object.
 
@@ -94,8 +94,8 @@
 Given the above ``'Cheddar Talk'`` blog example, this example would override the
 previous record in the database::
 
-    b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
-    b4.save()  # Overrides the previous blog with ID=3!
+    >>> b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
+    >>> b4.save()  # Overrides the previous blog with ID=3!
 
 See `How Django knows to UPDATE vs. INSERT`_, below, for the reason this
 happens.
@@ -187,6 +187,35 @@
 errors that are difficult to track down. This feature is for advanced use
 only.
 
+
+.. _ref-models-update:
+
+Updating objects
+================
+
+.. versionadded:: 1.1
+
+To update and save a model instance in one step, call ``update()``:
+
+.. method:: Model.update(**kwargs)
+
+A convenience method for updating and saving a model instance in one step,
+where the keyword arguments are the names of the fields on your model you want
+to update.  Like ``save()``, the ``update()`` method has no return value.
+
+Given the earlier ``'Not Cheddar'`` blog example, this example would update
+and save the existing model instance::
+
+    >>> b4.name
+    'Not Cheddar'
+    >>> b4.update(name='All Cheddar', tagline='Nothing but cheddar cheese')
+    >>> b4.name
+    'All Cheddar'
+
+Since ``update()`` calls ``save()`` behind the scenes, Django will hit the
+database every time ``update()`` is called.
+
+
 .. _model-instance-methods:
 
 Other model instance methods

=== modified file 'docs/ref/models/querysets.txt'
--- docs/ref/models/querysets.txt	2009-02-17 10:17:29 +0000
+++ docs/ref/models/querysets.txt	2009-03-15 17:03:00 +0000
@@ -896,6 +896,52 @@
 
 .. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
 
+``update_or_create(**kwargs)``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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.
+
+This method calls ``get_or_create()`` behind the scenes, and similarly
+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()`` will be used in a
+call to ``get_or_create()``. If ``get_or_create()`` creates an object, then
+nothing needs to be done by ``update_or_create()`` and a tuple of the created
+object and ``True`` is returned. If, on the other hand, ``get_or_create()``
+does not create a new object, then ``update_or_create()`` will update the
+object with the values passed in the ``defaults`` parameter and a tuple of
+the updated object and ``True`` is returned.
+
+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
+
 ``count()``
 ~~~~~~~~~~~
 

=== modified file 'tests/modeltests/update/models.py'
--- tests/modeltests/update/models.py	2008-08-09 17:19:44 +0000
+++ tests/modeltests/update/models.py	2009-03-15 16:28:04 +0000
@@ -1,6 +1,6 @@
 """
-Tests for the update() queryset method that allows in-place, multi-object
-updates.
+Tests for the update() queryset and model methods that allow in-place updates
+to multiple objects or a single object.
 """
 
 from django.db import models
@@ -22,13 +22,16 @@
 
 
 __test__ = {'API_TESTS': """
+# QuerySet method #############################################################
+
 >>> DataPoint(name="d0", value="apple").save()
 >>> DataPoint(name="d2", value="banana").save()
 >>> d3 = DataPoint.objects.create(name="d3", value="banana")
 >>> RelatedPoint(name="r1", data=d3).save()
 
 Objects are updated by first filtering the candidates into a queryset and then
-calling the update() method. It executes immediately and returns nothing.
+calling the update() method. It executes immediately and returns the number of
+objects affected.
 
 >>> DataPoint.objects.filter(value="apple").update(name="d1")
 1
@@ -74,5 +77,43 @@
     ...
 AssertionError: Cannot update a query once a slice has been taken.
 
+# Model method ################################################################
+
+# Get an existing DataPoint object.
+>>> d = DataPoint.objects.get(name="d2")
+>>> d.value, d.another_value
+(u'thing', u'peaches')
+
+# Update multiple fields.
+>>> d.update(value='oranges', another_value='apples')
+
+# Check that the object was updated.
+>>> d.value, d.another_value
+('oranges', 'apples')
+
+# Check that the object was saved.
+>>> d = DataPoint.objects.get(name="d2", value="oranges", another_value="apples")
+>>> d.value, d.another_value
+(u'oranges', u'apples')
+
+# Get an existing RelatedPoint object.
+>>> r = RelatedPoint.objects.get(name="r1")
+>>> r.data
+<DataPoint: d1>
+
+# Update the ForeignKey field.
+>>> r.update(data=d)
+>>> r.data
+<DataPoint: d2>
+
+# Check that the object was saved.
+>>> RelatedPoint.objects.get(name="r1").data
+<DataPoint: d2>
+
+# You can also update an object that has not yet been saved.
+>>> d = DataPoint(name="d4", value="planes", another_value="trains")
+>>> d.update(another_value="automobiles")
+>>> d.value, d.another_value
+('planes', 'automobiles')
 """
 }

=== added directory 'tests/modeltests/update_or_create'
=== added file 'tests/modeltests/update_or_create/__init__.py'
=== added file 'tests/modeltests/update_or_create/models.py'
--- tests/modeltests/update_or_create/models.py	1970-01-01 00:00:00 +0000
+++ tests/modeltests/update_or_create/models.py	2009-03-15 16:09:08 +0000
@@ -0,0 +1,73 @@
+"""
+update_or_create() tries to look up an object with the given parameters.
+If an object is found, it updates the object.  If an object isn't found, it
+creates one with the given parameters.
+"""
+
+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',)
+
+__test__ = {'API_TESTS': """
+# Create a Person.
+>>> from datetime import date
+>>> p = Person.objects.create(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
+
+# Only one Person is in the database at this point.
+>>> Person.objects.all()
+[<Person: John Lennon, Birthday: 1940-10-09>]
+
+# update_or_create() a Person with the same name.
+>>> p, created = Person.objects.update_or_create(first_name='John', last_name='Lennon', defaults={'birthday': date(1970, 10, 9)})
+
+# update_or_create() didn't have to create an object.
+>>> created
+False
+
+# There's still only one Person in the database, and their birthday was updated.
+>>> Person.objects.all()
+[<Person: John Lennon, Birthday: 1970-10-09>]
+
+# update_or_create() a Person with a different name.
+>>> p, created = Person.objects.update_or_create(first_name='George', last_name='Harrison', defaults={'birthday': date(1943, 2, 25)})
+>>> created
+True
+
+# Two People in the database now.
+>>> Person.objects.all()
+[<Person: George Harrison, Birthday: 1943-02-25>, <Person: John Lennon, Birthday: 1970-10-09>]
+
+# 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)})
+>>> created
+False
+
+# The two People in the database haven't changed.
+>>> Person.objects.all()
+[<Person: George Harrison, Birthday: 1943-02-25>, <Person: John Lennon, Birthday: 1970-10-09>]
+
+# 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={})
+>>> created
+False
+
+# 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={})
+>>> created
+True
+
+>>> Person.objects.all()
+[<Person: George Harrison, Birthday: 1943-02-25>, <Person: John Lennon, Birthday: 1970-10-09>, <Person: John Smith, Birthday: 1950-02-10>]
+"""}

