Django

Code

Ticket #3288: 3288.diff

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

fix and tests

  • django/db/models/query.py

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

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