Ticket #9961: select_related_depth.diff

File select_related_depth.diff, 4.3 KB (added by punteney, 6 years ago)

Updated patch to rev11528 and included tests and docs

  • django/db/models/sql/query.py

     
    13421342        (for example, cur_depth=1 means we are looking at models with direct
    13431343        connections to the root model).
    13441344        """
    1345         if not restricted and self.max_depth and cur_depth > self.max_depth:
     1345        if not restricted and self.max_depth is not None and cur_depth > self.max_depth:
    13461346            # We've recursed far enough; bail out.
    13471347            return
    13481348
  • django/db/models/query.py

     
    540540        If fields are specified, they must be ForeignKey fields and only those
    541541        related objects are included in the selection.
    542542        """
    543         depth = kwargs.pop('depth', 0)
     543        depth = kwargs.pop('depth', None)
    544544        if kwargs:
    545545            raise TypeError('Unexpected keyword arguments to select_related: %s'
    546546                    % (kwargs.keys(),))
     
    551551            obj.query.add_select_related(fields)
    552552        else:
    553553            obj.query.select_related = True
    554         if depth:
     554        if depth is not None:
    555555            obj.query.max_depth = depth
    556556        return obj
    557557
     
    947947    value_annotation = False
    948948
    949949
    950 def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
     950def get_cached_row(klass, row, index_start, max_depth=None, cur_depth=0,
    951951                   requested=None, offset=0, only_load=None):
    952952    """
    953953    Helper function that recursively returns an object with the specified
    954954    related attributes already populated.
    955955    """
    956     if max_depth and requested is None and cur_depth > max_depth:
     956    if max_depth is not None and requested is None and cur_depth > max_depth:
    957957        # We've recursed deeply enough; stop now.
    958958        return None
    959959
  • tests/modeltests/select_related/models.py

     
    147147>>> len(db.connection.queries)
    1481485
    149149
     150# If depth=0 then it shouldn't do the select_related
     151>>> db.reset_queries()
     152>>> world = Species.objects.all().select_related(depth=0)
     153>>> [o.genus.family.order for o in world]
     154[<Order: Diptera>, <Order: Primates>, <Order: Fabales>, <Order: Agaricales>]
     155>>> len(db.connection.queries)
     15613
     157
     158# If depth=0 then it shouldn't do the select_related
     159>>> db.reset_queries()
     160>>> world = Species.objects.all().select_related('genus').select_related(depth=0)
     161>>> [o.genus.family.order for o in world]
     162[<Order: Diptera>, <Order: Primates>, <Order: Fabales>, <Order: Agaricales>]
     163>>> len(db.connection.queries)
     16413
     165
     166# If depth=0 then it shouldn't do the select_related even if a previous select
     167# related was set on the query
     168>>> db.reset_queries()
     169>>> world = Species.objects.all().select_related('genus').select_related(depth=0)
     170>>> [o.genus.family.order for o in world]
     171[<Order: Diptera>, <Order: Primates>, <Order: Fabales>, <Order: Agaricales>]
     172>>> len(db.connection.queries)
     17313
     174
     175
    150176>>> s = Species.objects.all().select_related(depth=1).extra(select={'a': 'select_related_species.id + 10'})[0]
    151177>>> s.id + 10 == s.a
    152178True
  • docs/ref/models/querysets.txt

     
    577577    p = b.author         # Doesn't hit the database.
    578578    c = p.hometown       # Requires a database call.
    579579
     580You can also use the ``depth`` argument to cancel an existing
     581``select_related()`` on the query by setting ``depth`` to "0". For example
     582these three queries are equivalent::
     583
     584    b = Book.objects.get(id=4)
     585    b = Book.objects.select_related(depth=0).get(id=4)
     586    b = Book.objects.select_related('author').select_related(depth=0).get(id=4)
     587
    580588Sometimes you only want to access specific models that are related to your root
    581589model, not all of the related models. In these cases, you can pass the related
    582590field names to ``select_related()`` and it will only follow those relations.
Back to Top