Subclassed tastypie's ToOneField in order to provide caching for FK entries.
- Legacy-Id: 10927
This commit is contained in:
parent
781a552e07
commit
62cae36acd
|
@ -4,9 +4,11 @@ import datetime
|
|||
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
import tastypie
|
||||
from tastypie.api import Api
|
||||
from tastypie.bundle import Bundle
|
||||
from tastypie.serializers import Serializer as BaseSerializer
|
||||
|
@ -172,5 +174,42 @@ class TimedeltaField(ApiField):
|
|||
raise ApiFieldError("Datetime provided to '%s' field must be a string: %s" % (self.instance_name, value))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
|
||||
class ToOneField(tastypie.fields.ToOneField):
|
||||
"Subclass of tastypie.fields.ToOneField which adds caching in the dehydrate method."
|
||||
|
||||
def dehydrate(self, bundle, for_list=True):
|
||||
foreign_obj = None
|
||||
|
||||
if callable(self.attribute):
|
||||
previous_obj = bundle.obj
|
||||
foreign_obj = self.attribute(bundle)
|
||||
elif isinstance(self.attribute, six.string_types):
|
||||
foreign_obj = bundle.obj
|
||||
|
||||
for attr in self._attrs:
|
||||
previous_obj = foreign_obj
|
||||
try:
|
||||
foreign_obj = getattr(foreign_obj, attr, None)
|
||||
except ObjectDoesNotExist:
|
||||
foreign_obj = None
|
||||
|
||||
if not foreign_obj:
|
||||
if not self.null:
|
||||
if callable(self.attribute):
|
||||
raise ApiFieldError("The related resource for resource %s could not be found." % (previous_obj))
|
||||
else:
|
||||
raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attr))
|
||||
return None
|
||||
|
||||
fk_resource = self.get_related_resource(foreign_obj)
|
||||
|
||||
# Up to this point we've copied the code from tastypie 0.13.1. Now
|
||||
# we add caching.
|
||||
cache_key = fk_resource.generate_cache_key('related', for_list=for_list)
|
||||
dehydrated = fk_resource._meta.cache.get(cache_key)
|
||||
if dehydrated is None:
|
||||
fk_bundle = Bundle(obj=foreign_obj, request=bundle.request)
|
||||
dehydrated = self.dehydrate_related(fk_bundle, fk_resource, for_list=for_list)
|
||||
fk_resource._meta.cache.set(cache_key, dehydrated)
|
||||
return dehydrated
|
||||
|
|
|
@ -16,10 +16,12 @@ from tastypie.resources import ModelResource
|
|||
|
||||
resource_head_template = """# Autogenerated by the makeresources management command {{date}}
|
||||
from tastypie.resources import ModelResource
|
||||
from tastypie.fields import ToOneField, ToManyField # pyflakes:ignore
|
||||
from tastypie.fields import ToManyField # pyflakes:ignore
|
||||
from tastypie.constants import ALL, ALL_WITH_RELATIONS # pyflakes:ignore
|
||||
from tastypie.cache import SimpleCache
|
||||
|
||||
from ietf import api
|
||||
from ietf.api import ToOneField # pyflakes:ignore
|
||||
|
||||
from {{app}}.models import * # pyflakes:ignore
|
||||
"""
|
||||
|
@ -33,6 +35,7 @@ class {{model.name}}Resource(ModelResource):{% if model.foreign_keys %}{% for fk
|
|||
class Meta:
|
||||
queryset = {{model.name}}.objects.all()
|
||||
serializer = api.Serializer()
|
||||
cache = SimpleCache()
|
||||
#resource_name = '{{model.resource_name}}'
|
||||
filtering = { {% for name in model.plain_names %}
|
||||
"{{ name }}": ALL,{%endfor%}{% for name in model.fk_names%}
|
||||
|
|
Loading…
Reference in a new issue