# How to prefetch related objects in Django Tastypie resources
# TLDR
You just need to use Django's
prefetch_related
(opens new window)
as usual on the resource's queryset
attribute. For example:
class UserResource(ModelResource):
jobs = fields.ToManyField(JobResource, 'jobs', full=True)
class Meta:
queryset = User.objects.prefetch_related('jobs').all()
2
3
4
# Background
Django Tastypie allows you to add relationship
fields (opens new window)
to resources (opens new window)
which will let Tastypie return related objects in its response.
For example, we might want to return all of the user's jobs along with the user itself:
class UserResource(ModelResource):
jobs = fields.ToManyField(JobResource, 'jobs', full=True)
class Meta:
queryset = User.objects.all()
2
3
4
The response will be something like:
{
"meta": {
...
"total_count": 2
},
"objects": [
{
"first_name": "Test",
"last_name": "Example",
"jobs": [
{
"id": 1,
"resource_uri": "/api/v1/job/1/",
"title": "Job 1"
},
{
"id": 2,
"resource_uri": "/api/v1/job/2/",
"title": "Job 2"
}
},
...
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
However, if we're not careful, relationship fields can add tons of extra database queries.
Django's
prefetch_related
(opens new window)
method for querysets allows us to "prefetch" related objects by fetching them
all in one query instead of one-by-one.
# Prefetching in Tastypie resources
I thought that Tastypie might have built-in support for prefetching related
objects, but it does not. You simply need to alter the queryset
attribute of
your resource and use prefetch_related
as you would normally in Django:
class UserResource(ModelResource):
jobs = fields.ToManyField(JobResource, 'jobs', full=True)
class Meta:
queryset = User.objects.prefetch_related('jobs').all()
2
3
4
Sometimes you might want to return sub-relationships as well. For example, you
might want to fetch all of the users with all of their jobs plus the locations of their jobs. You can then add the sub-relationship to the prefetch_related
call as
well:
class JobResource(ModelResource):
locations = fields.ToManyField(LocationResource, 'locations', full=True)
class Meta:
queryset = Job.objects.all()
class UserResource(ModelResource):
jobs = fields.ToManyField(JobResource, 'jobs', full=True)
class Meta:
queryset = User.objects.prefetch_related('jobs__locations').all()
2
3
4
5
6
7
8
9
Newsletter
If you'd like to subscribe to my blog, please enter your details below. You can unsubscribe at any time.