Author: mtredinnick
Date: 2008-02-22 19:34:49 -0600 (Fri, 22 Feb 2008)
New Revision: 7147
Modified:
django/branches/queryset-refactor/django/db/backends/__init__.py
django/branches/queryset-refactor/django/db/backends/mysql/base.py
django/branches/queryset-refactor/django/db/backends/mysql_old/base.py
django/branches/queryset-refactor/django/db/backends/postgresql/operations.py
django/branches/queryset-refactor/django/db/backends/sqlite3/base.py
django/branches/queryset-refactor/django/db/models/sql/query.py
django/branches/queryset-refactor/docs/db-api.txt
django/branches/queryset-refactor/tests/modeltests/basic/models.py
Log:
queryset-refactor: Implemented slicing to end of querysets.
Refs #2150, #5012.
Modified: django/branches/queryset-refactor/django/db/backends/__init__.py
===================================================================
--- django/branches/queryset-refactor/django/db/backends/__init__.py
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/backends/__init__.py
2008-02-23 01:34:49 UTC (rev 7147)
@@ -183,6 +183,14 @@
"""
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
Modified: django/branches/queryset-refactor/django/db/backends/mysql/base.py
===================================================================
--- django/branches/queryset-refactor/django/db/backends/mysql/base.py
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/backends/mysql/base.py
2008-02-23 01:34:49 UTC (rev 7147)
@@ -93,6 +93,10 @@
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.
Modified: django/branches/queryset-refactor/django/db/backends/mysql_old/base.py
===================================================================
--- django/branches/queryset-refactor/django/db/backends/mysql_old/base.py
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/backends/mysql_old/base.py
2008-02-23 01:34:49 UTC (rev 7147)
@@ -98,6 +98,10 @@
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.
Modified:
django/branches/queryset-refactor/django/db/backends/postgresql/operations.py
===================================================================
---
django/branches/queryset-refactor/django/db/backends/postgresql/operations.py
2008-02-23 00:23:57 UTC (rev 7146)
+++
django/branches/queryset-refactor/django/db/backends/postgresql/operations.py
2008-02-23 01:34:49 UTC (rev 7147)
@@ -31,6 +31,9 @@
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.
Modified: django/branches/queryset-refactor/django/db/backends/sqlite3/base.py
===================================================================
--- django/branches/queryset-refactor/django/db/backends/sqlite3/base.py
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/backends/sqlite3/base.py
2008-02-23 01:34:49 UTC (rev 7147)
@@ -63,6 +63,9 @@
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
Modified: django/branches/queryset-refactor/django/db/models/sql/query.py
===================================================================
--- django/branches/queryset-refactor/django/db/models/sql/query.py
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/models/sql/query.py
2008-02-23 01:34:49 UTC (rev 7147)
@@ -262,11 +262,15 @@
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)
Modified: django/branches/queryset-refactor/docs/db-api.txt
===================================================================
--- django/branches/queryset-refactor/docs/db-api.txt 2008-02-23 00:23:57 UTC
(rev 7146)
+++ django/branches/queryset-refactor/docs/db-api.txt 2008-02-23 01:34:49 UTC
(rev 7147)
@@ -422,6 +422,14 @@
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
Modified: django/branches/queryset-refactor/tests/modeltests/basic/models.py
===================================================================
--- django/branches/queryset-refactor/tests/modeltests/basic/models.py
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/tests/modeltests/basic/models.py
2008-02-23 01:34:49 UTC (rev 7147)
@@ -292,11 +292,9 @@
>>> 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)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---