Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

queryset-refactor: Implemented slicing to end of querysets.

Refs #2150, #5012.


git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7147 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 7355fa6b728357a3e7257fbe1175d68a0d7e2ec1 1 parent e2f524c
@malcolmt malcolmt authored
View
8 django/db/backends/__init__.py
@@ -183,6 +183,14 @@ def max_name_length(self):
"""
return None
+ def no_limit_value(self):
+ """
+ Returns the value to use for the LIMIT when we are wanting "LIMIT
+ infinity". Returns None if the limit clause can be omitted in this case.
+ """
+ # FIXME: API may need to change once Oracle backend is repaired.
+ raise NotImplementedError()
+
def pk_default_value(self):
"""
Returns the value to use during an INSERT statement to specify that
View
4 django/db/backends/mysql/base.py
@@ -93,6 +93,10 @@ def limit_offset_sql(self, limit, offset=None):
sql += "%s," % offset
return sql + str(limit)
+ def no_limit_value(self):
+ # 2**64 - 1, as recommended by the MySQL documentation
+ return 18446744073709551615L
+
def quote_name(self, name):
if name.startswith("`") and name.endswith("`"):
return name # Quoting once is enough.
View
4 django/db/backends/mysql_old/base.py
@@ -98,6 +98,10 @@ def limit_offset_sql(self, limit, offset=None):
sql += "%s," % offset
return sql + str(limit)
+ def no_limit_value(self):
+ # 2**64 - 1, as recommended by the MySQL documentation
+ return 18446744073709551615L
+
def quote_name(self, name):
if name.startswith("`") and name.endswith("`"):
return name # Quoting once is enough.
View
3  django/db/backends/postgresql/operations.py
@@ -31,6 +31,9 @@ def last_insert_id(self, cursor, table_name, pk_name):
cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name))
return cursor.fetchone()[0]
+ def no_limit_value(self):
+ return None
+
def quote_name(self, name):
if name.startswith('"') and name.endswith('"'):
return name # Quoting once is enough.
View
3  django/db/backends/sqlite3/base.py
@@ -63,6 +63,9 @@ def quote_name(self, name):
return name # Quoting once is enough.
return '"%s"' % name
+ def no_limit_value(self):
+ return -1
+
def sql_flush(self, style, tables, sequences):
# NB: The generated SQL below is specific to SQLite
# Note: The DELETE FROM... SQL generated below works for SQLite databases
View
6 django/db/models/sql/query.py
@@ -262,11 +262,15 @@ def as_sql(self, with_limits=True):
if ordering:
result.append('ORDER BY %s' % ', '.join(ordering))
+ # FIXME: Pull this out to make life easier for Oracle et al.
if with_limits:
if self.high_mark:
result.append('LIMIT %d' % (self.high_mark - self.low_mark))
if self.low_mark:
- assert self.high_mark, "'offset' is not allowed without 'limit'"
+ if not self.high_mark:
+ val = self.connection.ops.no_limit_value()
+ if val:
+ result.append('LIMIT %d' % val)
result.append('OFFSET %d' % self.low_mark)
params.extend(self.extra_params)
View
8 docs/db-api.txt
@@ -422,6 +422,14 @@ This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``)::
Entry.objects.all()[5:10]
+You can also slice from the item ''N'' to the end of the queryset. For
+example, to return everything from the fixth item onwards::
+
+ Entry.objects.all()[5:]
+
+How this last example is implemented in SQL varies depending upon the database
+used, but it is supported in all cases.
+
Generally, slicing a ``QuerySet`` returns a new ``QuerySet`` -- it doesn't
evaluate the query. An exception is if you use the "step" parameter of Python
slice syntax. For example, this would actually execute the query in order to
View
8 tests/modeltests/basic/models.py
@@ -292,11 +292,9 @@ def __unicode__(self):
>>> Article.objects.all()[2:][2:3]
[<Article: Default headline>]
-# Note that you can't use 'offset' without 'limit' (on some dbs), so this doesn't work:
->>> Article.objects.all()[2:]
-Traceback (most recent call last):
- ...
-AssertionError: 'offset' is not allowed without 'limit'
+# Using an offset without a limit is also possible.
+>>> Article.objects.all()[5:]
+[<Article: Fourth article>, <Article: Article 7>, <Article: Updated article 8>]
# Also, once you have sliced you can't filter, re-order or combine
>>> Article.objects.all()[0:5].filter(id=1)

0 comments on commit 7355fa6

Please sign in to comment.
Something went wrong with that request. Please try again.