Changeset 4645
- Timestamp:
- 02/28/07 09:24:05 (2 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/db/models/query.py
r4563 r4645 85 85 self._order_by = None # Ordering, e.g. ('date', '-name'). If None, use model's ordering. 86 86 self._select_related = False # Whether to fill cache for related objects. 87 self._max_related_depth = 0 # Maximum "depth" for select_related 87 88 self._distinct = False # Whether the query should use SELECT DISTINCT. 88 89 self._select = {} # Dictionary of attname -> SQL. … … 187 188 for row in rows: 188 189 if fill_cache: 189 obj, index_end = get_cached_row(self.model, row, 0) 190 obj, index_end = get_cached_row(klass=self.model, row=row, 191 index_start=0, max_depth=self._max_related_depth) 190 192 else: 191 193 obj = self.model(*row[:index_end]) … … 395 397 return self._filter_or_exclude(None, **filter_obj) 396 398 397 def select_related(self, true_or_false=True ):399 def select_related(self, true_or_false=True, depth=0): 398 400 "Returns a new QuerySet instance with '_select_related' modified." 399 return self._clone(_select_related=true_or_false )401 return self._clone(_select_related=true_or_false, _max_related_depth=depth) 400 402 401 403 def order_by(self, *field_names): … … 431 433 c._order_by = self._order_by 432 434 c._select_related = self._select_related 435 c._max_related_depth = self._max_related_depth 433 436 c._distinct = self._distinct 434 437 c._select = self._select.copy() … … 484 487 # Add additional tables and WHERE clauses based on select_related. 485 488 if self._select_related: 486 fill_table_cache(opts, select, tables, where, opts.db_table, [opts.db_table]) 489 fill_table_cache(opts, select, tables, where, 490 old_prefix=opts.db_table, 491 cache_tables_seen=[opts.db_table], 492 max_depth=self._max_related_depth) 487 493 488 494 # Add any additional SELECTs. … … 729 735 raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type) 730 736 731 def get_cached_row(klass, row, index_start): 732 "Helper function that recursively returns an object with cache filled" 737 def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0): 738 """Helper function that recursively returns an object with cache filled""" 739 740 # If we've got a max_depth set and we've exceeded that depth, bail now. 741 if max_depth and cur_depth > max_depth: 742 return None 743 733 744 index_end = index_start + len(klass._meta.fields) 734 745 obj = klass(*row[index_start:index_end]) 735 746 for f in klass._meta.fields: 736 747 if f.rel and not f.null: 737 rel_obj, index_end = get_cached_row(f.rel.to, row, index_end) 738 setattr(obj, f.get_cache_name(), rel_obj) 748 cached_row = get_cached_row(f.rel.to, row, index_end, max_depth, cur_depth+1) 749 if cached_row: 750 rel_obj, index_end = cached_row 751 setattr(obj, f.get_cache_name(), rel_obj) 739 752 return obj, index_end 740 753 741 def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen ):754 def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen, max_depth=0, cur_depth=0): 742 755 """ 743 756 Helper function that recursively populates the select, tables and where (in 744 757 place) for select_related queries. 745 758 """ 759 760 # If we've got a max_depth set and we've exceeded that depth, bail now. 761 if max_depth and cur_depth > max_depth: 762 return None 763 746 764 qn = backend.quote_name 747 765 for f in opts.fields: … … 758 776 (qn(old_prefix), qn(f.column), qn(db_table), qn(f.rel.get_related_field().column))) 759 777 select.extend(['%s.%s' % (qn(db_table), qn(f2.column)) for f2 in f.rel.to._meta.fields]) 760 fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen )778 fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen, max_depth, cur_depth+1) 761 779 762 780 def parse_lookup(kwarg_items, opts): django/trunk/docs/db-api.txt
r4636 r4645 597 597 ``null=True``. 598 598 599 Usually, using ``select_related()`` can vastly improve performance since your 600 app can avoid many database calls. However, in situations with deeply nested 601 sets of relationships ``select_related()`` can sometimes end up following "too 602 many" relations, and can generate queries so large that they end up being slow. 603 604 In these situations, you can use the ``depth`` argument to ``select_related()`` 605 to control how many "levels" of relations ``select_related()`` will actually 606 follow:: 607 608 b = Book.objects.select_related(depth=1).get(id=4) 609 p = b.author # Doesn't hit the database. 610 c = p.hometown # Requires a database call. 611 599 612 ``extra(select=None, where=None, params=None, tables=None)`` 600 613 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
