Ticket #7961: django_extra.diff
File django_extra.diff, 5.7 KB (added by , 16 years ago) |
---|
-
db/models/query.py
625 625 # names of the model fields to select. 626 626 627 627 def iterator(self): 628 if (not self.extra_names and 629 len(self.field_names) != len(self.model._meta.fields)): 630 self.query.trim_extra_select(self.extra_names) 628 self.query.trim_extra_select(self.extra_names) 631 629 names = self.query.extra_select.keys() + self.field_names 632 630 for row in self.query.results_iter(): 633 631 yield dict(zip(names, row)) -
db/models/sql/query.py
78 78 79 79 # These are for extensions. The contents are more or less appended 80 80 # verbatim to the appropriate clause. 81 self.extra_select = {}# Maps col_alias -> col_sql.82 self.extra_select_params = ()81 self.extra_select = SortedDict() # Maps col_alias -> col_sql. 82 self.extra_select_params = SortedDict() 83 83 self.extra_tables = () 84 84 self.extra_where = () 85 85 self.extra_params = () … … 182 182 obj.related_select_cols = [] 183 183 obj.max_depth = self.max_depth 184 184 obj.extra_select = self.extra_select.copy() 185 obj.extra_select_params = self.extra_select_params 185 obj.extra_select_params = self.extra_select_params.copy() 186 186 obj.extra_tables = self.extra_tables 187 187 obj.extra_where = self.extra_where 188 188 obj.extra_params = self.extra_params … … 255 255 # get_from_clause() for details. 256 256 from_, f_params = self.get_from_clause() 257 257 258 where, w_params = self.where.as_sql(qn=self.quote_name_unless_alias) 259 params = list(self.extra_select_params) 260 258 where, w_params = self.where.as_sql(qn=self.quote_name_unless_alias) 259 params = [] 260 for extra_select_param in self.extra_select_params.values(): 261 params.extend(extra_select_param) 262 261 263 result = ['SELECT'] 262 264 if self.distinct: 263 265 result.append('DISTINCT') … … 1503 1505 self.distinct = False 1504 1506 self.select = [select] 1505 1507 self.select_fields = [None] 1506 self.extra_select = {}1507 self.extra_select_params = ()1508 self.extra_select = SortedDict() 1509 self.extra_select_params = SortedDict() 1508 1510 1509 1511 def add_select_related(self, fields): 1510 1512 """ … … 1526 1528 Adds data to the various extra_* attributes for user-created additions 1527 1529 to the query. 1528 1530 """ 1529 if select: 1530 # The extra select might be ordered (because it will be accepting 1531 # parameters). 1532 if (isinstance(select, SortedDict) and 1533 not isinstance(self.extra_select, SortedDict)): 1534 self.extra_select = SortedDict(self.extra_select) 1535 self.extra_select.update(select) 1536 if select_params: 1537 self.extra_select_params += tuple(select_params) 1531 if select: 1532 select = SortedDict(select) 1533 self.extra_select.append(select) 1534 if select_params: 1535 start = 0 1536 for key in select.keys(): 1537 number_of_params = select[key].count(" %s") # a %s in a sql statement is always preceded by a space, but could be at the very end of the string and then not be followed by a space 1538 self.extra_select_params.append({key:select_params[start:start+number_of_params]}) 1539 start += number_of_params 1540 if start != len(select_params): 1541 raise ValueError("The number of parameters expected by select= (%d) is not equal to the number of parameters given in select_params= (%d)" % (start, len(select_params))) 1538 1542 if where: 1539 1543 self.extra_where += tuple(where) 1540 1544 if params: … … 1547 1551 def trim_extra_select(self, names): 1548 1552 """ 1549 1553 Removes any aliases in the extra_select dictionary that aren't in 1550 'names'. 1554 'names'. 1555 Additionally remove the parameters that belonged to the removed aliases, 1556 this ensures that the parameters stay aligned with the '%s'-replacements in the query 1551 1557 1552 1558 This is needed if we are selecting certain values that don't incldue 1553 1559 all of the extra_select names. 1554 """ 1555 for key in set(self.extra_select).difference(set(names)): 1556 del self.extra_select[key] 1560 """ 1561 for key in reversed(self.extra_select.keys()): 1562 if key not in names: 1563 del self.extra_select[key] 1564 if self.extra_select_params.has_key(key): # sometimes a select statement has no params 1565 del self.extra_select_params[key] 1557 1566 1558 1567 def set_start(self, start): 1559 1568 """ … … 1674 1683 sender._meta._join_cache = {} 1675 1684 1676 1685 dispatcher.connect(setup_join_cache, signal=signals.class_prepared) 1677 1686 -
utils/datastructures.py
121 121 def update(self, dict_): 122 122 for k, v in dict_.items(): 123 123 self.__setitem__(k, v) 124 125 def append(self, data): 126 for key, value in data.iteritems(): 127 super(SortedDict, self).__setitem__(key, value) 128 self.keyOrder.append(key) 124 129 125 130 def setdefault(self, key, default): 126 131 if key not in self.keyOrder: … … 406 411 return self.func(value) 407 412 return value 408 413 414