Last active
December 18, 2015 01:29
-
-
Save jneight/5704096 to your computer and use it in GitHub Desktop.
Avoid doing extra database queries when resource uri of related field is built using models PK.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding=utf-8 | |
from tastypie.bundle import Bundle | |
from tastypie import fields | |
from tastypie.exceptions import ApiFieldError | |
class OptimizedToOneField(fields.ToOneField): | |
def dehydrate(self, bundle, **kwargs): | |
""" | |
This modified field, allow to include resource_uri of related | |
resources without doing another database query. | |
Using select_related() in resource.meta.queryset also avoids | |
doing extra queries for each object, can be used instead | |
of this class | |
""" | |
if not self.full: | |
pk = getattr(bundle.obj, self.attribute + "_id", None) | |
if not pk: | |
if not self.null: | |
raise ApiFieldError( | |
"""The model '%r' has an empty attribute '%s' | |
and doesn't allow a null value.""" % | |
(bundle.obj, self.attribute)) | |
return None | |
# just create a temporal object with only PK | |
temporal_obj = type('TemporalModel', (object,), {'pk': pk})() | |
# from this point, is almost the same stuff that tastypie does. | |
self.fk_resource = self.get_related_resource(temporal_obj) | |
fk_bundle = Bundle( | |
obj=temporal_obj, request=bundle.request) | |
return self.dehydrate_related(fk_bundle, self.fk_resource) | |
return super(OptimizedToOneField, self).dehydrate(bundle, **kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment