1
0
mirror of https://github.com/django/django.git synced 2025-07-06 02:39:12 +00:00

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
This commit is contained in:
Malcolm Tredinnick 2008-02-23 01:34:49 +00:00
parent e2f524ca09
commit 7355fa6b72
8 changed files with 38 additions and 6 deletions

View File

@ -183,6 +183,14 @@ class BaseDatabaseOperations(object):
""" """
return None 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): def pk_default_value(self):
""" """
Returns the value to use during an INSERT statement to specify that Returns the value to use during an INSERT statement to specify that

View File

@ -93,6 +93,10 @@ class DatabaseOperations(BaseDatabaseOperations):
sql += "%s," % offset sql += "%s," % offset
return sql + str(limit) 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): def quote_name(self, name):
if name.startswith("`") and name.endswith("`"): if name.startswith("`") and name.endswith("`"):
return name # Quoting once is enough. return name # Quoting once is enough.

View File

@ -98,6 +98,10 @@ class DatabaseOperations(BaseDatabaseOperations):
sql += "%s," % offset sql += "%s," % offset
return sql + str(limit) 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): def quote_name(self, name):
if name.startswith("`") and name.endswith("`"): if name.startswith("`") and name.endswith("`"):
return name # Quoting once is enough. return name # Quoting once is enough.

View File

@ -31,6 +31,9 @@ class DatabaseOperations(BaseDatabaseOperations):
cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name)) cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name))
return cursor.fetchone()[0] return cursor.fetchone()[0]
def no_limit_value(self):
return None
def quote_name(self, name): def quote_name(self, name):
if name.startswith('"') and name.endswith('"'): if name.startswith('"') and name.endswith('"'):
return name # Quoting once is enough. return name # Quoting once is enough.

View File

@ -63,6 +63,9 @@ class DatabaseOperations(BaseDatabaseOperations):
return name # Quoting once is enough. return name # Quoting once is enough.
return '"%s"' % name return '"%s"' % name
def no_limit_value(self):
return -1
def sql_flush(self, style, tables, sequences): def sql_flush(self, style, tables, sequences):
# NB: The generated SQL below is specific to SQLite # NB: The generated SQL below is specific to SQLite
# Note: The DELETE FROM... SQL generated below works for SQLite databases # Note: The DELETE FROM... SQL generated below works for SQLite databases

View File

@ -262,11 +262,15 @@ class Query(object):
if ordering: if ordering:
result.append('ORDER BY %s' % ', '.join(ordering)) result.append('ORDER BY %s' % ', '.join(ordering))
# FIXME: Pull this out to make life easier for Oracle et al.
if with_limits: if with_limits:
if self.high_mark: if self.high_mark:
result.append('LIMIT %d' % (self.high_mark - self.low_mark)) result.append('LIMIT %d' % (self.high_mark - self.low_mark))
if 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) result.append('OFFSET %d' % self.low_mark)
params.extend(self.extra_params) params.extend(self.extra_params)

View File

@ -422,6 +422,14 @@ This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``)::
Entry.objects.all()[5:10] 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 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 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 slice syntax. For example, this would actually execute the query in order to

View File

@ -292,11 +292,9 @@ datetime.datetime(2005, 7, 28, 0, 0)
>>> Article.objects.all()[2:][2:3] >>> Article.objects.all()[2:][2:3]
[<Article: Default headline>] [<Article: Default headline>]
# Note that you can't use 'offset' without 'limit' (on some dbs), so this doesn't work: # Using an offset without a limit is also possible.
>>> Article.objects.all()[2:] >>> Article.objects.all()[5:]
Traceback (most recent call last): [<Article: Fourth article>, <Article: Article 7>, <Article: Updated article 8>]
...
AssertionError: 'offset' is not allowed without 'limit'
# Also, once you have sliced you can't filter, re-order or combine # Also, once you have sliced you can't filter, re-order or combine
>>> Article.objects.all()[0:5].filter(id=1) >>> Article.objects.all()[0:5].filter(id=1)