54c3191 INSERT/UPDATE distinction option
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index f627b54..abb45c7 100644
a
|
b
|
class BaseDatabaseFeatures(object):
|
314 | 314 | has_select_for_update_nowait = False |
315 | 315 | |
316 | 316 | supports_joins = True |
| 317 | distinguishes_insert_from_update = True |
317 | 318 | supports_select_related = True |
318 | 319 | supports_deleting_related_objects = True |
319 | 320 | |
diff --git a/django/db/models/base.py b/django/db/models/base.py
index ebd67be..39598ef 100644
a
|
b
|
class Model(object):
|
366 | 366 | pass |
367 | 367 | if kwargs: |
368 | 368 | raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]) |
| 369 | self._original_pk = self.pk if self._meta.pk is not None else None |
369 | 370 | super(Model, self).__init__() |
370 | 371 | signals.post_init.send(sender=self.__class__, instance=self) |
371 | 372 | |
… |
… |
class Model(object):
|
474 | 475 | ('raw', 'cls', and 'origin'). |
475 | 476 | """ |
476 | 477 | using = using or router.db_for_write(self.__class__, instance=self) |
| 478 | entity_exists = not self._state.adding or self._original_pk == self.pk |
477 | 479 | assert not (force_insert and force_update) |
478 | 480 | if cls is None: |
479 | 481 | cls = self.__class__ |
… |
… |
class Model(object):
|
519 | 521 | pk_set = pk_val is not None |
520 | 522 | record_exists = True |
521 | 523 | manager = cls._base_manager |
522 | | if pk_set: |
| 524 | # TODO/NONREL: Some backends could emulate force_insert/_update |
| 525 | # with an optimistic transaction, but since it's costly we should |
| 526 | # only do it when the user explicitly wants it. |
| 527 | # By adding support for an optimistic locking transaction |
| 528 | # in Django (SQL: SELECT ... FOR UPDATE) we could even make that |
| 529 | # part fully reusable on all backends (the current .exists() |
| 530 | # check below isn't really safe if you have lots of concurrent |
| 531 | # requests. BTW, and neither is QuerySet.get_or_create). |
| 532 | try_update = connections[using].features.distinguishes_insert_from_update |
| 533 | if not try_update: |
| 534 | record_exists = False |
| 535 | |
| 536 | if try_update and pk_set: |
523 | 537 | # Determine whether a record with the primary key already exists. |
524 | 538 | if (force_update or (not force_insert and |
525 | 539 | manager.using(using).filter(pk=pk_val).exists())): |