Ticket #3288: 3288_96.diff

File 3288_96.diff, 3.5 KB (added by PhiR, 7 years ago)

fix and tests, backported to 0.96

  • django/db/models/query.py

    diff -uri /home/Philippe/Django-0.96/django/db/models/query.py ./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

    diff -uri /home/Philippe/Django-0.96/tests/modeltests/select_related/models.py ./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")
Back to Top