Ticket #3288: 3288.diff

File 3288.diff, 3.4 KB (added by PhiR, 8 years ago)

fix and tests

  • django/db/models/query.py

     
    501501
    502502        # Add additional tables and WHERE clauses based on select_related.
    503503        if self._select_related:
    504             fill_table_cache(opts, select, tables, where,
     504            fill_table_cache(self.model, select, tables, where,
    505505                             old_prefix=opts.db_table,
    506506                             cache_tables_seen=[opts.db_table],
    507507                             max_depth=self._max_related_depth)
     
    845845                setattr(obj, f.get_cache_name(), rel_obj)
    846846    return obj, index_end
    847847
    848 def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen, max_depth=0, cur_depth=0):
     848def fill_table_cache(cls, select, tables, where, old_prefix, cache_tables_seen, max_depth=0, cur_depth=0):
    849849    """
    850850    Helper function that recursively populates the select, tables and where (in
    851851    place) for select_related queries.
     
    855855    if max_depth and cur_depth > max_depth:
    856856        return None
    857857
     858    opts = cls._meta
    858859    qn = connection.ops.quote_name
    859860    for f in opts.fields:
    860         if f.rel and not f.null:
     861        # we only visit FKs, and exclude those that can be null and those who point to our own Model
     862        if f.rel and not f.null and f.rel.to != cls:
    861863            db_table = f.rel.to._meta.db_table
    862864            if db_table not in cache_tables_seen:
    863865                tables.append(qn(db_table))
     
    869871            where.append('%s.%s = %s.%s' % \
    870872                (qn(old_prefix), qn(f.column), qn(db_table), qn(f.rel.get_related_field().column)))
    871873            select.extend(['%s.%s' % (qn(db_table), qn(f2.column)) for f2 in f.rel.to._meta.fields])
    872             fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen, max_depth, cur_depth+1)
     874            fill_table_cache(f.rel.to, select, tables, where, db_table, cache_tables_seen, max_depth, cur_depth+1)
    873875
    874876def parse_lookup(kwarg_items, opts):
    875877    # Helper function that handles converting API kwargs
  • tests/modeltests/select_related/models.py

     
    7575        obj.save()
    7676        parent = obj
    7777
     78# tests that select_related doesn't follow this kind of FK
     79class Foo(models.Model):
     80    parent = models.ForeignKey('self')
     81
     82class ALoop(models.Model):
     83    b = models.ForeignKey('BLoop')
     84
     85class BLoop(models.Model):
     86    a = models.ForeignKey('BLoop')
     87
    7888__test__ = {'API_TESTS':"""
    7989
    8090# Set up.
     
    8393>>> from django.conf import settings
    8494>>> settings.DEBUG = True
    8595
     96# simply verify that it's possible en enable select related on this model
     97>>> Foo.objects.all().select_related()
     98[]
     99
     100# simply verify that it's possible en enable select related on this model
     101>>> ALoop.objects.all().select_related()
     102[]
     103>>> BLoop.objects.all().select_related()
     104[]
     105
    86106>>> create_tree("Eukaryota Animalia Anthropoda Insecta Diptera Drosophilidae Drosophila melanogaster")
    87107>>> create_tree("Eukaryota Animalia Chordata Mammalia Primates Hominidae Homo sapiens")
    88108>>> create_tree("Eukaryota Plantae Magnoliophyta Magnoliopsida Fabales Fabaceae Pisum sativum")
Back to Top