Ticket #17143: 17143.diff

File 17143.diff, 3.5 KB (added by calvinspealman, 4 years ago)

Demonstration of fix. needs review and feedback.

  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index be42d02..c26e8e3 100644
    a b def get_cached_row(row, index_start, using, klass_info, offset=0): 
    13551355        obj._state.db = using
    13561356        obj._state.adding = False
    13571357
     1358    parent_klass_info = klass_info
     1359
    13581360    # Instantiate related fields
    13591361    index_end = index_start + field_count + offset
    13601362    # Iterate over each related object, populating any
    def get_cached_row(row, index_start, using, klass_info, offset=0): 
    13801382    # descent into reverse relations unless explicitly requested
    13811383    for f, klass_info in reverse_related_fields:
    13821384        # Recursively retrieve the data for the related object
    1383         cached_row = get_cached_row(row, index_end, using, klass_info)
     1385        if parent_klass_info[0] in klass_info[0].__bases__:
     1386            subklass_row = (
     1387                (row[index_end],)
     1388                + row[:field_count]
     1389                + row[index_end + 1: index_end + klass_info[2]]
     1390                )
     1391            if field_names:
     1392                field_names = parent_klass_info[1]
     1393            else:
     1394                field_names = [kf.attname for kf in klass._meta.fields if kf.name != 'id']
     1395            klass_info = klass_info[:2] + (klass_info[2] + len(field_names),) + klass_info[3:]
     1396            klass_info[1][1:1] = field_names
     1397
     1398            cached_row = get_cached_row(subklass_row, 0, using, klass_info)
     1399        else:
     1400            cached_row = get_cached_row(row, index_end, using, klass_info)
    13841401        # If the recursive descent found an object, populate the
    13851402        # descriptor caches relevant to the object
    13861403        if cached_row:
  • tests/regressiontests/select_related_onetoone/models.py

    diff --git a/tests/regressiontests/select_related_onetoone/models.py b/tests/regressiontests/select_related_onetoone/models.py
    index 3d6da9b..6453007 100644
    a b class StatDetails(models.Model): 
    4444
    4545class AdvancedUserStat(UserStat):
    4646    karma = models.IntegerField()
     47    special = models.BooleanField(default=False)
    4748
    4849class Image(models.Model):
    4950    name = models.CharField(max_length=100)
  • tests/regressiontests/select_related_onetoone/tests.py

    diff --git a/tests/regressiontests/select_related_onetoone/tests.py b/tests/regressiontests/select_related_onetoone/tests.py
    index 643a0ff..ed952bc 100644
    a b class ReverseSelectRelatedTestCase(TestCase): 
    1919        user2 = User.objects.create(username="bob")
    2020        results2 = UserStatResult.objects.create(results='moar results')
    2121        advstat = AdvancedUserStat.objects.create(user=user2, posts=200, karma=5,
    22                                                   results=results2)
     22                                                  results=results2, special=True)
    2323        StatDetails.objects.create(base_stats=advstat, comments=250)
    2424
    2525    def test_basic(self):
    class ReverseSelectRelatedTestCase(TestCase): 
    7070    def test_follow_inheritance(self):
    7171        with self.assertNumQueries(1):
    7272            stat = UserStat.objects.select_related('user', 'advanceduserstat').get(posts=200)
     73            self.assertEqual(stat.advanceduserstat.special, True)
    7374            self.assertEqual(stat.advanceduserstat.posts, 200)
    7475            self.assertEqual(stat.user.username, 'bob')
    7576            self.assertEqual(stat.advanceduserstat.user.username, 'bob')
Back to Top