Author: mtredinnick
Date: 2008-08-28 12:18:05 -0500 (Thu, 28 Aug 2008)
New Revision: 8670

Modified:
   django/trunk/django/db/models/query.py
   django/trunk/docs/ref/models/instances.txt
   django/trunk/docs/ref/models/querysets.txt
Log:
Changed create() and get_or_create() to force an insert (not update an existing 
value).

Backwards incompatible if you are using manually-specific primary key values
and relying on the previously documented behaviour that the new values would
always exist in the database (i.e. it would update the existing entry).

Fixed #8419.


Modified: django/trunk/django/db/models/query.py
===================================================================
--- django/trunk/django/db/models/query.py      2008-08-28 16:33:11 UTC (rev 
8669)
+++ django/trunk/django/db/models/query.py      2008-08-28 17:18:05 UTC (rev 
8670)
@@ -308,7 +308,7 @@
         and returning the created object.
         """
         obj = self.model(**kwargs)
-        obj.save()
+        obj.save(force_insert=True)
         return obj
 
     def get_or_create(self, **kwargs):
@@ -328,7 +328,7 @@
                 params.update(defaults)
                 obj = self.model(**params)
                 sid = transaction.savepoint()
-                obj.save()
+                obj.save(force_insert=True)
                 transaction.savepoint_commit(sid)
                 return obj, True
             except IntegrityError, e:

Modified: django/trunk/docs/ref/models/instances.txt
===================================================================
--- django/trunk/docs/ref/models/instances.txt  2008-08-28 16:33:11 UTC (rev 
8669)
+++ django/trunk/docs/ref/models/instances.txt  2008-08-28 17:18:05 UTC (rev 
8670)
@@ -193,6 +193,8 @@
 primary-key value is unused. For more on this nuance, see `Explicitly 
specifying
 auto-primary-key values`_ above and `Forcing an INSERT or UPDATE`_ below.
 
+.. _ref-models-force-insert:
+
 Forcing an INSERT or UPDATE
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

Modified: django/trunk/docs/ref/models/querysets.txt
===================================================================
--- django/trunk/docs/ref/models/querysets.txt  2008-08-28 16:33:11 UTC (rev 
8669)
+++ django/trunk/docs/ref/models/querysets.txt  2008-08-28 17:18:05 UTC (rev 
8670)
@@ -556,10 +556,18 @@
 and::
 
     p = Person(first_name="Bruce", last_name="Springsteen")
-    p.save()
+    p.save(force_insert=True)
 
 are equivalent.
 
+The :ref:`force_insert <ref-models-force-insert>` parameter is documented
+elsewhere, but all it means is that a new object will always be created.
+Normally you won't need to worry about this. However, if your model contains a
+manual primary key value that you set and if that value already exists in the
+database, a call to ``create()`` will fail with an ``IntegrityError`` since
+primary keys must be unique. So remember to be prepared to handle the
+exception if you are using manual primary keys.
+
 ``get_or_create(**kwargs)``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -590,7 +598,7 @@
 ``get_or_create()`` returns a tuple of that object and ``False``. If an object
 is *not* found, ``get_or_create()`` will instantiate and save a new object,
 returning a tuple of the new object and ``True``. The new object will be
-created according to this algorithm::
+created roughly according to this algorithm::
 
     defaults = kwargs.pop('defaults', {})
     params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
@@ -601,13 +609,23 @@
 In English, that means start with any non-``'defaults'`` keyword argument that
 doesn't contain a double underscore (which would indicate a non-exact lookup).
 Then add the contents of ``defaults``, overriding any keys if necessary, and
-use the result as the keyword arguments to the model class.
+use the result as the keyword arguments to the model class. As hinted at
+above, this is a simplification of the algorithm that is used, but it contains
+all the pertinent details. The internal implementation has some more
+error-checking than this and handles some extra edge-conditions; if you're
+interested, read the code.
 
 If you have a field named ``defaults`` and want to use it as an exact lookup in
 ``get_or_create()``, just use ``'defaults__exact'``, like so::
 
     Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 
'baz'})
 
+
+The ``get_or_create()`` method has similar error behaviour to ``create()``
+when you are using manually specified primary keys. If an object needs to be
+created and the key already exists in the database, an ``IntegrityError`` will
+be raised.
+
 Finally, a word on using ``get_or_create()`` in Django views. As mentioned
 earlier, ``get_or_create()`` is mostly useful in scripts that need to parse
 data and create new records if existing ones aren't available. But if you need


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to