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. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8670 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
79348d4018
commit
c181734fa1
|
@ -308,7 +308,7 @@ class QuerySet(object):
|
||||||
and returning the created object.
|
and returning the created object.
|
||||||
"""
|
"""
|
||||||
obj = self.model(**kwargs)
|
obj = self.model(**kwargs)
|
||||||
obj.save()
|
obj.save(force_insert=True)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def get_or_create(self, **kwargs):
|
def get_or_create(self, **kwargs):
|
||||||
|
@ -328,7 +328,7 @@ class QuerySet(object):
|
||||||
params.update(defaults)
|
params.update(defaults)
|
||||||
obj = self.model(**params)
|
obj = self.model(**params)
|
||||||
sid = transaction.savepoint()
|
sid = transaction.savepoint()
|
||||||
obj.save()
|
obj.save(force_insert=True)
|
||||||
transaction.savepoint_commit(sid)
|
transaction.savepoint_commit(sid)
|
||||||
return obj, True
|
return obj, True
|
||||||
except IntegrityError, e:
|
except IntegrityError, e:
|
||||||
|
|
|
@ -193,6 +193,8 @@ value explicitly when saving new objects, if you cannot guarantee the
|
||||||
primary-key value is unused. For more on this nuance, see `Explicitly specifying
|
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.
|
auto-primary-key values`_ above and `Forcing an INSERT or UPDATE`_ below.
|
||||||
|
|
||||||
|
.. _ref-models-force-insert:
|
||||||
|
|
||||||
Forcing an INSERT or UPDATE
|
Forcing an INSERT or UPDATE
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -556,10 +556,18 @@ A convenience method for creating an object and saving it all in one step. Thus
|
||||||
and::
|
and::
|
||||||
|
|
||||||
p = Person(first_name="Bruce", last_name="Springsteen")
|
p = Person(first_name="Bruce", last_name="Springsteen")
|
||||||
p.save()
|
p.save(force_insert=True)
|
||||||
|
|
||||||
are equivalent.
|
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)``
|
``get_or_create(**kwargs)``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -590,7 +598,7 @@ called ``defaults`` -- will be used in a ``get()`` call. If an object is found,
|
||||||
``get_or_create()`` returns a tuple of that object and ``False``. If an object
|
``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,
|
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
|
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', {})
|
defaults = kwargs.pop('defaults', {})
|
||||||
params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
|
params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
|
||||||
|
@ -601,13 +609,23 @@ created according to this algorithm::
|
||||||
In English, that means start with any non-``'defaults'`` keyword argument that
|
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).
|
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
|
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
|
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::
|
``get_or_create()``, just use ``'defaults__exact'``, like so::
|
||||||
|
|
||||||
Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'})
|
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
|
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
|
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
|
data and create new records if existing ones aren't available. But if you need
|
||||||
|
|
Loading…
Reference in New Issue