Skip to content

Commit

Permalink
disable sideloading if envelope is explicitly disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
aleontiev committed Jan 30, 2017
1 parent eacc153 commit b7de56b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 24 deletions.
4 changes: 1 addition & 3 deletions dynamic_rest/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ class SideloadingProcessor(object):
typically smaller than their nested equivalent.
"""

prefix = settings.ADDITIONAL_PRIMARY_RESOURCE_PREFIX

def __init__(self, serializer, data):
"""Initializes and runs the processor.
Expand Down Expand Up @@ -107,7 +105,7 @@ def process(self, obj, parent=None, parent_key=None, depth=0):
# if the primary resource is embedded, add it to a prefixed key
if name == self.plural_name:
name = '%s%s' % (
self.prefix,
settings.ADDITIONAL_PRIMARY_RESOURCE_PREFIX,
name
)

Expand Down
51 changes: 31 additions & 20 deletions dynamic_rest/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from rest_framework.fields import SkipField
from rest_framework.utils.serializer_helpers import ReturnDict, ReturnList

from dynamic_rest.utils import unpack
from dynamic_rest.bases import DynamicSerializerBase
from dynamic_rest.conf import settings
from dynamic_rest.fields import DynamicRelationField
Expand Down Expand Up @@ -69,12 +68,11 @@ def data(self):
"""Get the data, after performing post-processing if necessary."""
if not hasattr(self, '_processed_data'):
data = super(DynamicListSerializer, self).data
data = SideloadingProcessor(self, data).data
self._processed_data = ReturnDict(
data,
SideloadingProcessor(self, data).data,
serializer=self
) if self.child.envelope else ReturnList(
unpack(data),
data,
serializer=self
)
return self._processed_data
Expand Down Expand Up @@ -163,27 +161,29 @@ def __init__(
debug=False,
dynamic=True,
embed=False,
envelope=False,
envelope=None,
**kwargs
):
"""
Custom initializer that builds `request_fields`.
Arguments:
instance: Instance to be managed by the serializer.
instance: Initial instance, used by updates.
data: Initial data, used by updates / creates.
only_fields: List of field names to render.
include_fields: List of field names to include.
exclude_fields: List of field names to exclude.
request_fields: map of field names that supports
inclusions, exclusions, and nested sideloads.
embed: If True, force the current representation to be embedded.
sideloading: if False, force embedding for all descendants
If True, force sideloading for all descendants
If None (default), respect individual embed parameters
dynamic: If False, ignore deferred rules and
revert to standard DRF `.fields` behavior.
envelope: if True, wrap `.data` in envelope.
if False, do not use an envelope.
request_fields: Map of field names that supports
nested inclusions / exclusions.
embed: If True, embed the current representation.
If False, sideload the current representation.
sideloading: If True, force sideloading for all descendents.
If False, force embedding for all descendents.
If None (default), respect descendents' embed parameters.
dynamic: If False, disable inclusion / exclusion features.
envelope: If True, wrap `.data` in an envelope.
If False, do not use an envelope and disable sideloading.
If None, do not use an envelope.
"""
name = self.get_name()
if data is not fields.empty and name in data and len(data) == 1:
Expand Down Expand Up @@ -213,11 +213,20 @@ def __init__(
super(WithDynamicSerializerMixin, self).__init__(**kwargs)

self.envelope = envelope
self.sideloading = sideloading
self.debug = debug
self.dynamic = dynamic
self.request_fields = request_fields or {}
self.embed = embed if sideloading is None else not sideloading

# sideloading modifies top-level response keys,
# so it requires an envelope
if envelope is False:
sideloading = False

# `embed` is overriden by `sideloading`
embed = embed if sideloading is None else not sideloading

self.sideloading = sideloading
self.embed = embed

self._dynamic_init(only_fields, include_fields, exclude_fields)
self.enable_optimization = settings.ENABLE_SERIALIZER_OPTIMIZATIONS
Expand Down Expand Up @@ -599,9 +608,11 @@ def id_only(self):
def data(self):
if not hasattr(self, '_processed_data'):
data = super(WithDynamicSerializerMixin, self).data
data = SideloadingProcessor(self, data).data
data = SideloadingProcessor(
self, data
).data if self.envelope else data
self._processed_data = ReturnDict(
data if self.envelope else unpack(data),
data,
serializer=self
)
return self._processed_data
Expand Down
4 changes: 4 additions & 0 deletions dynamic_rest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ def is_truthy(x):


def unpack(content):
if not content:
# empty values pass through
return content

keys = [k for k in content.keys() if k != 'meta']
unpacked = content[keys[0]]
return unpacked
2 changes: 1 addition & 1 deletion tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def test_get_one_with_include(self):
response = self.client.get('/users/1/?include[]=groups.')
self.assertEquals(200, response.status_code)
data = json.loads(response.content.decode('utf-8'))
self.assertEquals(len(data['groups']), 2)
self.assertEquals(len(data.get('groups', [])), 2)

def test_get_with_filter(self):
with self.assertNumQueries(1):
Expand Down

0 comments on commit b7de56b

Please sign in to comment.