Ticket #17340: insert-update-distinction.patch

File insert-update-distinction.patch, 2.5 KB (added by Jonas H., 12 years ago)
  • django/db/backends/__init__.py

    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):  
    314314    has_select_for_update_nowait = False
    315315
    316316    supports_joins = True
     317    distinguishes_insert_from_update = True
    317318    supports_select_related = True
    318319    supports_deleting_related_objects = True
    319320
  • django/db/models/base.py

    diff --git a/django/db/models/base.py b/django/db/models/base.py
    index ebd67be..39598ef 100644
    a b class Model(object):  
    366366                    pass
    367367            if kwargs:
    368368                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
    369370        super(Model, self).__init__()
    370371        signals.post_init.send(sender=self.__class__, instance=self)
    371372
    class Model(object):  
    474475        ('raw', 'cls', and 'origin').
    475476        """
    476477        using = using or router.db_for_write(self.__class__, instance=self)
     478        entity_exists = not self._state.adding or self._original_pk == self.pk
    477479        assert not (force_insert and force_update)
    478480        if cls is None:
    479481            cls = self.__class__
    class Model(object):  
    519521            pk_set = pk_val is not None
    520522            record_exists = True
    521523            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:
    523537                # Determine whether a record with the primary key already exists.
    524538                if (force_update or (not force_insert and
    525539                        manager.using(using).filter(pk=pk_val).exists())):
Back to Top