#10148 closed (invalid)
get_or_create function documentation is not clear enough
Reported by: | Batiste Bieler | Owned by: | nobody |
---|---|---|---|
Component: | Documentation | Version: | 1.0 |
Severity: | Keywords: | get_or_create, documentation | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
get_or_create function documentation doesn't tell that defauts dictionary argument won't override the attributes when an object already exist in the database:
import datetime from result.models import Game d = datetime.datetime(2009, 4, 18, 16, 1) g, c = Game.objects.get_or_create(id=116) g.start_date >>> datetime.datetime(2009, 4, 18, 16, 0) g, c = Game.objects.get_or_create(id=116, defaults={"start_date":d}) g.start_date >>> datetime.datetime(2009, 4, 18, 16, 0)
This comportement is not clear in the documentation and should be specified. Something like this is needed to be sure that the attributes are updated:
for k, v in game_attrs_update.items(): setattr(g, k, v)
Change History (4)
comment:1 by , 16 years ago
comment:2 by , 16 years ago
I figured out that the better way to achieve what I want is to do that:
g, c = Game.objects.get_or_create(id=116, **defaults)
comment:3 by , 16 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
The documentation on get_or_create says:
Any keyword arguments passed to ``get_or_create()`` -- *except* an optional one 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 is *not* found, ``get_or_create()`` will instantiate and save a new object, returning a tuple of the new object and ``True``.
(It also shows an example of using get_or_create
in terms of
get
and
create
.)
So, in your example, get_or_create
looks for a
Game
object with
id=116
, one is found and returned "as-is".
By the way, the "better way" you mention:
g, c = Game.objects.get_or_create(id=116, **defaults)
will look up a Game
object with
id=116
and
start_date=datetime.datetime(2009, 4, 18, 16, 1)
. This object isn't found, so one will be created. The result is an
IntegrityError
, since you're trying to use the same primary key for more than one object.
Closing as invalid since this seems to be clearly documented in both English and Python.
comment:4 by , 16 years ago
batiste, you might want to track #3182, which proposes adding an update_or_create
to
QuerySet
objects.
Sorry I just inversed the whole thing: