Skip to content

Instantly share code, notes, and snippets.

@loic
Last active December 20, 2015 11:29
Show Gist options
  • Select an option

  • Save loic/6124159 to your computer and use it in GitHub Desktop.

Select an option

Save loic/6124159 to your computer and use it in GitHub Desktop.
diff --git a/django/db/models/query.py b/django/db/models/query.py
index a3e0a95..84434df 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -149,10 +149,14 @@ class QuerySet(object):
"""
if not isinstance(k, (slice,) + six.integer_types):
raise TypeError
- assert ((not isinstance(k, slice) and (k >= 0))
- or (isinstance(k, slice) and (k.start is None or k.start >= 0)
- and (k.stop is None or k.stop >= 0))), \
- "Negative indexing is not supported."
+
+ assert (
+ not isinstance(k, slice) or (
+ isinstance(k, slice) and
+ (k.start is None or k.start >= 0) and
+ (k.stop is None or k.stop >= 0)
+ )
+ ), "Negative indexing is not supported."
if self._result_cache is not None:
return self._result_cache[k]
@@ -170,8 +174,13 @@ class QuerySet(object):
qs.query.set_limits(start, stop)
return list(qs)[::k.step] if k.step else qs
- qs = self._clone()
- qs.query.set_limits(k, k + 1)
+ if k >= 0:
+ qs = self._clone()
+ qs.query.set_limits(k, k + 1)
+ else:
+ k *= -1
+ qs = self.reverse() if self.ordered else self.order_by('-pk')
+ qs.query.set_limits(k - 1, k)
return list(qs)[0]
def __and__(self, other):
diff --git a/tests/basic/tests.py b/tests/basic/tests.py
index 55ed6a4..812e19b 100644
--- a/tests/basic/tests.py
+++ b/tests/basic/tests.py
@@ -440,15 +440,8 @@ class ModelTest(TestCase):
except Exception as e:
self.fail('Should raise an AssertionError, not %s' % e)
- # Negative slices are not supported, due to database constraints.
- # (hint: inverting your ordering might do what you need).
- try:
- Article.objects.all()[-1]
- self.fail('Should raise an AssertionError')
- except AssertionError as e:
- self.assertEqual(str(e), "Negative indexing is not supported.")
- except Exception as e:
- self.fail('Should raise an AssertionError, not %s' % e)
+ # Test negative indexing.
+ self.assertEqual(Article.objects.all()[-3], a4)
error = None
try:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment