In [1]:
posts = Post.objects.all()
In [2]:
print(posts.query)
In [3]:
print(
Post.objects
.select_related('author')
.query)
In [4]:
posts_startups = (
Post.objects.prefetch_related(
'startups',
)
)
In [5]:
list(posts_startups) == list(posts)
Out[5]:
In [6]:
str(posts.query) == str(posts_startups.query)
Out[6]:
In [7]:
print(posts_startups.query)
In [8]:
from django.db import connection
from pprint import pprint
In [9]:
print(connection.queries[-1]['sql'])
In [10]:
print(connection.queries[-2]['sql'])
# a prefetch causes a new query
In [11]:
from django.db import reset_queries
reset_queries()
In [12]:
pprint(connection.queries)
In [13]:
posts = Post.objects.prefetch_related('startups')
In [14]:
# the queryset never evaluated!
pprint(connection.queries)
In [15]:
posts = list(posts) # force evaluation
In [16]:
# two queries:
# the first for Post,
# the second for Startups related to the Post
pprint(connection.queries)
In [17]:
reset_queries()
# three queries:
# first for Post,
# the second for Startups associated with those Posts
# and then for the Tags associated with the Startups
posts = list(
Post.objects.prefetch_related(
'startups__tags'
),
)
posts_conn = connection.queries
pprint(posts_conn)
In [18]:
reset_queries()
# the following query is redundant
posts = list(
Post.objects.prefetch_related(
'startups',
'startups__tags'
),
)
posts_conn == connection.queries
Out[18]:
In [19]:
reset_queries()
posts = list(
Post.objects.prefetch_related(
Prefetch(
'startups__tags',
),
)
)
posts_conn == connection.queries
Out[19]:
In [20]:
posts = list(
Post.objects.prefetch_related(
Prefetch(
'startups__tags',
queryset=Tag.objects.all(),
to_attr='cached_tags',
),
)
)
In [21]:
# make sure none of the code calls the database!
reset_queries()
In [22]:
posts
Out[22]:
In [23]:
django_training = posts[3]
In [24]:
django_training.startups.all()
Out[24]:
In [25]:
type(django_training.startups.all())
Out[25]:
In [26]:
jambon_software = django_training.startups.all()[0]
jambon_software.cached_tags
Out[26]:
In [27]:
type(jambon_software.cached_tags)
Out[27]:
In [28]:
# no database calls!
pprint(connection.queries)
In [29]:
jambon_software.tags.all()
Out[29]:
In [30]:
pprint(connection.queries)
In [31]:
reset_queries()
startups = list(
Startup.objects.prefetch_related(
Prefetch(
'blog_posts',
queryset=(
Post.objects
.select_related(
'author__profile')),
to_attr='cached_posts',
),
Prefetch(
'cached_posts__tags',
to_attr='cached_post_tags',
),
Prefetch(
'tags',
to_attr='cached_tags',
),
Prefetch(
'cached_tags__startup_set',
),
)
)
len(connection.queries)
Out[31]:
In [32]:
reset_queries()
startups
Out[32]:
In [33]:
jambon_software = startups[3]
In [34]:
jambon_software.cached_posts
Out[34]:
In [35]:
django_training = jambon_software.cached_posts[0]
django_training.author
Out[35]:
In [36]:
django_training.author.profile.name
Out[36]:
In [37]:
django_training.cached_post_tags
Out[37]:
In [38]:
jambon_software.cached_tags
Out[38]:
In [39]:
django = jambon_software.cached_tags[0]
django.startup_set.all()
Out[39]:
In [40]:
for startup in startups:
print(
'{} has the following competitors:'
.format(startup))
for tag in startup.cached_tags:
for competitor in tag.startup_set.all():
if competitor.pk != startup.pk:
print(
' {}'
.format(competitor))
In [41]:
pprint(connection.queries)
In [42]:
list(Tag.objects.values('name', 'slug'))
Out[42]:
In [43]:
print(Tag.objects.values('name', 'slug').query)
In [44]:
list(Tag.objects.values_list('name', flat=True))
Out[44]:
In [45]:
print(Tag.objects.values_list('name', flat=True).query)
In [46]:
print(Tag.objects.all().query)
In [47]:
print(Tag.objects.defer('slug').query)
In [48]:
print(Tag.objects.defer('id').query)
In [49]:
from django.core.exceptions import FieldDoesNotExist
try:
tags = list(Tag.objects.defer('pk'))
except FieldDoesNotExist as e:
print(e)
In [50]:
print(Tag.objects.only('name').query)
In [51]:
str(Tag.objects.defer('slug').query) == str(Tag.objects.only('name').query)
Out[51]:
In [52]:
print(Tag.objects.only('name').values().query)
In [53]:
try:
tags = Tag.objects.values().only('name')
except NotImplementedError as e:
print(e)