Changeset 6603
- Timestamp:
- 10/23/07 23:22:23 (10 months ago)
- Files:
-
- django/branches/queryset-refactor/django/db/models/query.py (modified) (3 diffs)
- django/branches/queryset-refactor/django/db/models/sql/query.py (modified) (5 diffs)
- django/branches/queryset-refactor/docs/db-api.txt (modified) (1 diff)
- django/branches/queryset-refactor/tests/regressiontests/queries/models.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/queryset-refactor/django/db/models/query.py
r6600 r6603 89 89 index_end = len(self.model._meta.fields) 90 90 extra_select = self.query.extra_select.keys() 91 extra_select.sort()92 91 for row in self.query.results_iter(): 93 92 if fill_cache: … … 379 378 380 379 def iterator(self): 381 extra_select = self.query.extra_select.keys() 382 extra_select.sort() 383 if extra_select: 384 self.field_names.extend([f for f in extra_select]) 385 380 self.field_names.extend([f for f in self.query.extra_select.keys()]) 386 381 for row in self.query.results_iter(): 387 382 yield dict(zip(self.field_names, row)) … … 410 405 raise FieldDoesNotExist('%s has no field named %r' 411 406 % (opts.object_name, e.args[0])) 412 field_names = self._fields407 field_names = list(self._fields) 413 408 else: 414 409 fields = [] django/branches/queryset-refactor/django/db/models/sql/query.py
r6521 r6603 11 11 import re 12 12 13 from django.utils import tree 13 from django.utils.tree import Node 14 from django.utils.datastructures import SortedDict 14 15 from django.db.models.sql.where import WhereNode, AND, OR 15 16 from django.db.models.sql.datastructures import Count, Date … … 95 96 # These are for extensions. The contents are more or less appended 96 97 # verbatim to the appropriate clause. 97 self.extra_select = {}# Maps col_alias -> col_sql.98 self.extra_select = SortedDict() # Maps col_alias -> col_sql. 98 99 self.extra_tables = [] 99 100 self.extra_where = [] … … 365 366 aliases = result[:] 366 367 367 # We sort extra_select so that the result columns are in a well-defined368 # order (and thus QuerySet.iterator can extract them correctly).369 extra_select = self.extra_select.items()370 extra_select.sort()371 368 result.extend(['(%s) AS %s' % (col, alias) 372 for alias, col in extra_select])369 for alias, col in self.extra_select.items()]) 373 370 aliases.extend(self.extra_select.keys()) 374 371 … … 762 759 763 760 for child in q_object.children: 764 if isinstance(child, tree.Node):761 if isinstance(child, Node): 765 762 self.where.start_subtree(q_object.connection) 766 763 self.add_q(child) … … 938 935 self.distinct = False 939 936 self.select = [select] 940 self.extra_select = {}937 self.extra_select = SortedDict() 941 938 942 939 def execute_sql(self, result_type=MULTI): django/branches/queryset-refactor/docs/db-api.txt
r6600 r6603 821 821 subqueries. 822 822 823 **New in Django development version** 824 In some rare cases, you might wish to pass parameters to the SQL fragments 825 in ``extra(select=...)```. Since the ``params`` attribute is a sequence 826 and the ``select`` attribute is a dictionary, some care is required so 827 that the parameters are matched up correctly with the extra select pieces. 828 Firstly, in this situation, you should use a 829 ``django.utils.datastructures.SortedDict`` for the ``select`` value, not 830 just a normal Python dictionary. Secondly, make sure that your parameters 831 for the ``select`` come first in the list and that you have not passed any 832 parameters to an earlier ``extra()`` call for this queryset. 833 834 This will work:: 835 836 Blog.objects.extra( 837 select=SortedDict(('a', '%s'), ('b', '%s')), 838 params=('one', 'two')) 839 840 ... while this won't:: 841 842 # Will not work! 843 Blog.objects.extra(where=['foo=%s'], params=('bar',)).extra( 844 select=SortedDict(('a', '%s'), ('b', '%s')), 845 params=('one', 'two')) 846 847 In the second example, the earlier ``params`` usage will mess up the later 848 one. So always put your extra select pieces in the first ``extra()`` call 849 if you need to use parameters in them. 850 823 851 ``where`` / ``tables`` 824 852 You can define explicit SQL ``WHERE`` clauses -- perhaps to perform django/branches/queryset-refactor/tests/regressiontests/queries/models.py
r6600 r6603 380 380 >>> id(q1) == id(q1.all()) 381 381 False 382 383 Bug #2902 384 Parameters can be given to extra_select, *if* you use a SortedDict. 385 386 (First we need to know which order the keys fall in "naturally" on your system, 387 so we can put things in the wrong way around from normal. A normal dict would 388 thus fail.) 389 >>> from django.utils.datastructures import SortedDict 390 >>> s = [('a', '%s'), ('b', '%s')] 391 >>> params = ['one', 'two'] 392 >>> if {'a': 1, 'b': 2}.keys() == ['a', 'b']: 393 ... s.reverse() 394 ... params.reverse() 395 >>> Item.objects.extra(select=SortedDict(s), params=params).values('a','b')[0] 396 {'a': u'one', 'b': u'two'} 382 397 """} 383 398
