#31321: Unexpected behavior of `update_or_create`, misleading flag `created`
-------------------------------------+-------------------------------------
Reporter: | Owner: nobody
plushchaynikolay |
Type: | Status: new
Cleanup/optimization |
Component: Database | Version: 3.0
layer (models, ORM) | Keywords: get_or_create
Severity: Normal | update_or_create created
Triage Stage: | primary_key
Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 1
UI/UX: 0 |
-------------------------------------+-------------------------------------
Unexpected behavior of `update_or_create` (and `get_or_create`) when
accidentally overrode primary_key with None-value.
It was primarily unexpected because of misleading naming of flag
`created`.
{{{
. . .
self.assertEqual(MyModel.objects.count(), 1)
# ok
_, created = MyModel.objects.update_or_create(
somefield=obj.somefield,
defaults={**model_to_dict(obj)}
)
self.assertFalse(created)
# ok
self.assertEqual(MyModel.objects.count(), 1)
# AssertionError: 2 != 1
}}}
`created == False` but `MyModel.objects.count() == 2`, and new object was
actually created.
{{{
>>> model_to_dict(obj)
{'id': None, 'somefield': 'once told me'}
}}}
The field `id` (primary key) is overridden with `None` from
`defaults={**model_to_dict(obj)}`, and when it does`obj.save()`, then
`obj.id` is auto incremented with new value. (Same with `get_or_create`)
We understand that the issue took it's place because of our unknowing of
how this functions work inside. But actually we shouldn't know it.
Also have some suggestions, if You don't mind:
- rename `created` into `found`
- carefully explain this issue in documentation
- check if field is autoincrementable and overridden to a None-value
and ignore overriding
- check if field is autoincrementable and overridden to a None-value
and make a warning
[https://github.com/plushchaynikolay/dj-bug more], desu
--
Ticket URL: <https://code.djangoproject.com/ticket/31321>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/059.407b4279c2f346e1b5d94afdc9bbdca7%40djangoproject.com.