Last active
August 29, 2015 13:57
-
-
Save spiner2000/9390154 to your computer and use it in GitHub Desktop.
Tastypie fields order
This file contains 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
import json | |
from collections import OrderedDict | |
from tastypie.serializers import Serializer | |
from tastypie import fields | |
from tastypie.resources import Resource | |
from django.core.serializers.json import DjangoJSONEncoder | |
class OrderedSerializer(Serializer): | |
def to_json(self, data, options=None): | |
options = options or {} | |
data = self.to_simple(data, options) | |
return json.dumps(data, cls=DjangoJSONEncoder, sort_keys=False) | |
def to_simple(self, data, options): | |
if isinstance(data, Bundle): | |
return OrderedDict((key, self.to_simple(val, options)) for (key, val) in data.data.items()) | |
return super(OrderedSerializer, self).to_simple( data, options) | |
class SomeResource(Resource): | |
first_name = fields.fields.CharField(attribute='first_name',) | |
last_name = fields.fields.CharField(attribute='last_name',) | |
class Meta: | |
resource_name = 'someresource' | |
serializer = OrderedSerializer() | |
field_order = ['first_name','last_name'] | |
def full_dehydrate(self, bundle, for_list=False): | |
""" | |
Given a bundle with an object instance, extract the information from it | |
to populate the resource. | |
""" | |
use_in = ['all', 'list' if for_list else 'detail'] | |
""" | |
Convert bundle data to OrderedDict | |
""" | |
bundle.data = OrderedDict(bundle.data) | |
# Dehydrate each field. | |
items = self.fields.items() | |
## make data ordered | |
for field in self._meta.field_order: | |
for field_name, field_object in items: | |
if field_name == field: | |
## | |
# If it's not for use in this mode, skip | |
field_use_in = getattr(field_object, 'use_in', 'all') | |
if callable(field_use_in): | |
if not field_use_in(bundle): | |
continue | |
else: | |
if field_use_in not in use_in: | |
continue | |
# A touch leaky but it makes URI resolution work. | |
if getattr(field_object, 'dehydrated_type', None) == 'related': | |
field_object.api_name = self._meta.api_name | |
field_object.resource_name = self._meta.resource_name | |
bundle.data[field_name] = field_object.dehydrate(bundle, for_list=for_list) | |
# Check for an optional method to do further dehydration. | |
method = getattr(self, "dehydrate_%s" % field_name, None) | |
if method: | |
bundle.data[field_name] = method(bundle) | |
bundle = self.dehydrate(bundle) | |
return bundle | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment