mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Fixed #18177 -- Cached known related instances.
This was recently fixed for one-to-one relations; this patch adds support for foreign keys. Thanks kaiser.yann for the report and the initial version of the patch.
This commit is contained in:
0
tests/modeltests/known_related_objects/__init__.py
Normal file
0
tests/modeltests/known_related_objects/__init__.py
Normal file
@@ -0,0 +1,65 @@
|
||||
[
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "known_related_objects.tournament",
|
||||
"fields": {
|
||||
"name": "Tourney 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "known_related_objects.tournament",
|
||||
"fields": {
|
||||
"name": "Tourney 2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "known_related_objects.pool",
|
||||
"fields": {
|
||||
"tournament": 1,
|
||||
"name": "T1 Pool 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "known_related_objects.pool",
|
||||
"fields": {
|
||||
"tournament": 1,
|
||||
"name": "T1 Pool 2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "known_related_objects.pool",
|
||||
"fields": {
|
||||
"tournament": 2,
|
||||
"name": "T2 Pool 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "known_related_objects.pool",
|
||||
"fields": {
|
||||
"tournament": 2,
|
||||
"name": "T2 Pool 2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "known_related_objects.poolstyle",
|
||||
"fields": {
|
||||
"name": "T1 Pool 2 Style",
|
||||
"pool": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "known_related_objects.poolstyle",
|
||||
"fields": {
|
||||
"name": "T2 Pool 1 Style",
|
||||
"pool": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
19
tests/modeltests/known_related_objects/models.py
Normal file
19
tests/modeltests/known_related_objects/models.py
Normal file
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
Existing related object instance caching.
|
||||
|
||||
Test that queries are not redone when going back through known relations.
|
||||
"""
|
||||
|
||||
from django.db import models
|
||||
|
||||
class Tournament(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
|
||||
class Pool(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
tournament = models.ForeignKey(Tournament)
|
||||
|
||||
class PoolStyle(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
pool = models.OneToOneField(Pool)
|
||||
|
||||
88
tests/modeltests/known_related_objects/tests.py
Normal file
88
tests/modeltests/known_related_objects/tests.py
Normal file
@@ -0,0 +1,88 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from .models import Tournament, Pool, PoolStyle
|
||||
|
||||
class ExistingRelatedInstancesTests(TestCase):
|
||||
fixtures = ['tournament.json']
|
||||
|
||||
def test_foreign_key(self):
|
||||
with self.assertNumQueries(2):
|
||||
tournament = Tournament.objects.get(pk=1)
|
||||
pool = tournament.pool_set.all()[0]
|
||||
self.assertIs(tournament, pool.tournament)
|
||||
|
||||
def test_foreign_key_prefetch_related(self):
|
||||
with self.assertNumQueries(2):
|
||||
tournament = (Tournament.objects.prefetch_related('pool_set').get(pk=1))
|
||||
pool = tournament.pool_set.all()[0]
|
||||
self.assertIs(tournament, pool.tournament)
|
||||
|
||||
def test_foreign_key_multiple_prefetch(self):
|
||||
with self.assertNumQueries(2):
|
||||
tournaments = list(Tournament.objects.prefetch_related('pool_set'))
|
||||
pool1 = tournaments[0].pool_set.all()[0]
|
||||
self.assertIs(tournaments[0], pool1.tournament)
|
||||
pool2 = tournaments[1].pool_set.all()[0]
|
||||
self.assertIs(tournaments[1], pool2.tournament)
|
||||
|
||||
def test_one_to_one(self):
|
||||
with self.assertNumQueries(2):
|
||||
style = PoolStyle.objects.get(pk=1)
|
||||
pool = style.pool
|
||||
self.assertIs(style, pool.poolstyle)
|
||||
|
||||
def test_one_to_one_select_related(self):
|
||||
with self.assertNumQueries(1):
|
||||
style = PoolStyle.objects.select_related('pool').get(pk=1)
|
||||
pool = style.pool
|
||||
self.assertIs(style, pool.poolstyle)
|
||||
|
||||
def test_one_to_one_multi_select_related(self):
|
||||
with self.assertNumQueries(1):
|
||||
poolstyles = list(PoolStyle.objects.select_related('pool'))
|
||||
self.assertIs(poolstyles[0], poolstyles[0].pool.poolstyle)
|
||||
self.assertIs(poolstyles[1], poolstyles[1].pool.poolstyle)
|
||||
|
||||
def test_one_to_one_prefetch_related(self):
|
||||
with self.assertNumQueries(2):
|
||||
style = PoolStyle.objects.prefetch_related('pool').get(pk=1)
|
||||
pool = style.pool
|
||||
self.assertIs(style, pool.poolstyle)
|
||||
|
||||
def test_one_to_one_multi_prefetch_related(self):
|
||||
with self.assertNumQueries(2):
|
||||
poolstyles = list(PoolStyle.objects.prefetch_related('pool'))
|
||||
self.assertIs(poolstyles[0], poolstyles[0].pool.poolstyle)
|
||||
self.assertIs(poolstyles[1], poolstyles[1].pool.poolstyle)
|
||||
|
||||
def test_reverse_one_to_one(self):
|
||||
with self.assertNumQueries(2):
|
||||
pool = Pool.objects.get(pk=2)
|
||||
style = pool.poolstyle
|
||||
self.assertIs(pool, style.pool)
|
||||
|
||||
def test_reverse_one_to_one_select_related(self):
|
||||
with self.assertNumQueries(1):
|
||||
pool = Pool.objects.select_related('poolstyle').get(pk=2)
|
||||
style = pool.poolstyle
|
||||
self.assertIs(pool, style.pool)
|
||||
|
||||
def test_reverse_one_to_one_prefetch_related(self):
|
||||
with self.assertNumQueries(2):
|
||||
pool = Pool.objects.prefetch_related('poolstyle').get(pk=2)
|
||||
style = pool.poolstyle
|
||||
self.assertIs(pool, style.pool)
|
||||
|
||||
def test_reverse_one_to_one_multi_select_related(self):
|
||||
with self.assertNumQueries(1):
|
||||
pools = list(Pool.objects.select_related('poolstyle'))
|
||||
self.assertIs(pools[1], pools[1].poolstyle.pool)
|
||||
self.assertIs(pools[2], pools[2].poolstyle.pool)
|
||||
|
||||
def test_reverse_one_to_one_multi_prefetch_related(self):
|
||||
with self.assertNumQueries(2):
|
||||
pools = list(Pool.objects.prefetch_related('poolstyle'))
|
||||
self.assertIs(pools[1], pools[1].poolstyle.pool)
|
||||
self.assertIs(pools[2], pools[2].poolstyle.pool)
|
||||
Reference in New Issue
Block a user