浏览代码

Fixed #12806 -- Added an implementation of `RawQuerySet.__getitem__`. Thanks, Bruno Renié.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12504 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Justin Bronn 15 年之前
父节点
当前提交
c4699b0b8a
共有 5 个文件被更改,包括 35 次插入2 次删除
  1. 1 0
      AUTHORS
  2. 3 0
      django/db/models/query.py
  3. 1 1
      django/db/models/sql/query.py
  4. 14 0
      docs/topics/db/sql.txt
  5. 16 1
      tests/modeltests/raw_query/tests.py

+ 1 - 0
AUTHORS

@@ -503,6 +503,7 @@ answer newbie questions, and generally made Django that much better:
     Cheng Zhang
     Glenn Maynard <glenn@zewt.org>
     bthomas
+    Bruno Renié <buburno@gmail.com>
 
 A big THANK YOU goes to:
 

+ 3 - 0
django/db/models/query.py

@@ -1334,6 +1334,9 @@ class RawQuerySet(object):
     def __repr__(self):
         return "<RawQuerySet: %r>" % (self.raw_query % self.params)
 
+    def __getitem__(self, k):
+        return list(self)[k]
+
     @property
     def db(self):
         "Return the database that will be used if this query is executed now"

+ 1 - 1
django/db/models/sql/query.py

@@ -54,7 +54,7 @@ class RawQuery(object):
 
     def __iter__(self):
         # Always execute a new query for a new iterator.
-        # This could be optomized with a cache at the expense of RAM.
+        # This could be optimized with a cache at the expense of RAM.
         self._execute_query()
         return iter(self.cursor)
 

+ 14 - 0
docs/topics/db/sql.txt

@@ -91,6 +91,20 @@ query could also be written::
     >>> name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
     >>> Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
 
+Index lookups
+-------------
+
+``raw()`` supports indexing, so if you need only the first result you can
+write::
+
+    >>> first_person = Person.objects.raw('SELECT * from myapp_person')[0]
+
+However, the indexing and slicing are not performed at the database level. If
+you have a big amount of ``Person`` objects in your database, it would be more
+efficient to limit the query at the SQL level::
+
+    >>> first_person = Person.objects.raw('SELECT * from myapp_person LIMIT 1')[0]
+
 Deferring model fields
 ----------------------
 

+ 16 - 1
tests/modeltests/raw_query/tests.py

@@ -185,4 +185,19 @@ class RawQueryTests(TestCase):
             self.assertEqual(normal_authors[index], raw_author)
             second_iterations += 1
 
-        self.assertEqual(first_iterations, second_iterations)
+        self.assertEqual(first_iterations, second_iterations)
+
+    def testGetItem(self):
+        # Indexing on RawQuerySets
+        query = "SELECT * FROM raw_query_author ORDER BY id ASC"
+        third_author = Author.objects.raw(query)[2]
+        self.assertEqual(third_author.first_name, 'Bob')
+
+        first_two = Author.objects.raw(query)[0:2]
+        self.assertEquals(len(first_two), 2)
+
+        try:
+            Author.objects.raw(query)['test']
+            self.fail('Index lookups should only accept int, long or slice')
+        except TypeError:
+            pass