Django

Code

Ticket #3288: 3288_96.diff

File 3288_96.diff, 3.5 kB (added by PhiR, 10 months ago)

fix and tests, backported to 0.96

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

    old new  
    488488 
    489489        # Add additional tables and WHERE clauses based on select_related. 
    490490        if self._select_related: 
    491             fill_table_cache(opts, select, tables, where,  
     491            fill_table_cache(self.model, select, tables, where,  
    492492                             old_prefix=opts.db_table,  
    493493                             cache_tables_seen=[opts.db_table],  
    494494                             max_depth=self._max_related_depth) 
     
    753753                setattr(obj, f.get_cache_name(), rel_obj) 
    754754    return obj, index_end 
    755755 
    756 def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen, max_depth=0, cur_depth=0): 
     756def fill_table_cache(cls, select, tables, where, old_prefix, cache_tables_seen, max_depth=0, cur_depth=0): 
    757757    """ 
    758758    Helper function that recursively populates the select, tables and where (in 
    759759    place) for select_related queries. 
     
    763763    if max_depth and cur_depth > max_depth: 
    764764        return None 
    765765     
     766    opts = cls._meta 
    766767    qn = backend.quote_name 
    767768    for f in opts.fields: 
    768         if f.rel and not f.null: 
     769        # we only visit FKs, and exclude those that can be null and those who point to our own Model 
     770        if f.rel and not f.null and f.rel.to != cls: 
    769771            db_table = f.rel.to._meta.db_table 
    770772            if db_table not in cache_tables_seen: 
    771773                tables.append(qn(db_table)) 
     
    777779            where.append('%s.%s = %s.%s' % \ 
    778780                (qn(old_prefix), qn(f.column), qn(db_table), qn(f.rel.get_related_field().column))) 
    779781            select.extend(['%s.%s' % (qn(db_table), qn(f2.column)) for f2 in f.rel.to._meta.fields]) 
    780             fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen, max_depth, cur_depth+1) 
     782            fill_table_cache(f.rel.to, select, tables, where, db_table, cache_tables_seen, max_depth, cur_depth+1) 
    781783 
    782784def parse_lookup(kwarg_items, opts): 
    783785    # Helper function that handles converting API kwargs 
  • ./tests/modeltests/select_related/models.py

    old new  
    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")