diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index b149a94f19..e8e9720d85 100644 --- a/django/db/backends/__init__.py +++ b/django/db/backends/__init__.py @@ -755,6 +755,9 @@ class BaseDatabaseFeatures(object): uppercases_column_names = False + # Does the backend support "select for update" queries with limit (and offset)? + supports_select_for_update_with_limit = True + def __init__(self, connection): self.connection = connection diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 3260eee0bd..4e055133a0 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -120,6 +120,8 @@ class DatabaseFeatures(BaseDatabaseFeatures): closed_cursor_error_class = InterfaceError bare_select_suffix = " FROM DUAL" uppercases_column_names = True + # select for update with limit can be achieved on Oracle, but not with the current backend. + supports_select_for_update_with_limit = False class DatabaseOperations(BaseDatabaseOperations): diff --git a/django/db/models/query.py b/django/db/models/query.py index a0967f0fd9..942ee7efa3 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -345,7 +345,9 @@ class QuerySet(object): clone = self.filter(*args, **kwargs) if self.query.can_filter(): clone = clone.order_by() - clone = clone[:MAX_GET_RESULTS + 1] + if (not clone.query.select_for_update or + connections[self.db].features.supports_select_for_update_with_limit): + clone = clone[:MAX_GET_RESULTS + 1] num = len(clone) if num == 1: return clone._result_cache[0] diff --git a/tests/select_for_update/tests.py b/tests/select_for_update/tests.py index 5d126844d2..3fae8c9ffe 100644 --- a/tests/select_for_update/tests.py +++ b/tests/select_for_update/tests.py @@ -292,3 +292,9 @@ class SelectForUpdateTests(TransactionTestCase): self.assertEqual(router.db_for_write(Person), query.db) finally: router.routers = old_routers + + @skipUnlessDBFeature('has_select_for_update') + def test_select_for_update_with_get(self): + with transaction.atomic(): + person = Person.objects.select_for_update().get(name='Reinhardt') + self.assertEqual(person.name, 'Reinhardt')