Skip to content

Commit

Permalink
Fixes django-tastypie#850. Instead of using path to determin if we ar…
Browse files Browse the repository at this point in the history
…e dehydrating a list of resources or a single resource, we explicitly pass a boolean. This should also make writing tests easier as we no longer need to have path defined for requests.
  • Loading branch information
numan committed Apr 22, 2013
1 parent f06f41f commit 01e620a
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 17 deletions.
20 changes: 10 additions & 10 deletions tastypie/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def default(self):

return self._default

def dehydrate(self, bundle):
def dehydrate(self, bundle, for_list=True):
"""
Takes data from the provided object and prepares it for the
resource.
Expand Down Expand Up @@ -545,12 +545,12 @@ def to_class(self):

return self._to_class

def dehydrate_related(self, bundle, related_resource):
def dehydrate_related(self, bundle, related_resource, for_list=True):
"""
Based on the ``full_resource``, returns either the endpoint or the data
from ``full_dehydrate`` for the related resource.
"""
should_dehydrate_full_resource = self.should_full_dehydrate(bundle)
should_dehydrate_full_resource = self.should_full_dehydrate(bundle, for_list=for_list)

if not should_dehydrate_full_resource:
# Be a good netizen.
Expand Down Expand Up @@ -665,14 +665,14 @@ def build_related_resource(self, value, request=None, related_obj=None, related_
else:
raise ApiFieldError("The '%s' field was given data that was not a URI, not a dictionary-alike and does not have a 'pk' attribute: %s." % (self.instance_name, value))

def should_full_dehydrate(self, bundle):
def should_full_dehydrate(self, bundle, for_list):
"""
Based on the ``full``, ``list_full`` and ``detail_full`` returns ``True`` or ``False``
indicating weather the resource should be fully dehydrated.
"""
should_dehydrate_full_resource = False
if self.full:
is_details_view = resolve(bundle.request.path).url_name == "api_dispatch_detail"
is_details_view = not for_list
if is_details_view:
if (not callable(self.full_detail) and self.full_detail) or (callable(self.full_detail) and self.full_detail(bundle)):
should_dehydrate_full_resource = True
Expand Down Expand Up @@ -702,7 +702,7 @@ def __init__(self, to, attribute, related_name=None, default=NOT_PROVIDED,
)
self.fk_resource = None

def dehydrate(self, bundle):
def dehydrate(self, bundle, for_list=True):
foreign_obj = None

if isinstance(self.attribute, basestring):
Expand All @@ -726,7 +726,7 @@ def dehydrate(self, bundle):

self.fk_resource = self.get_related_resource(foreign_obj)
fk_bundle = Bundle(obj=foreign_obj, request=bundle.request)
return self.dehydrate_related(fk_bundle, self.fk_resource)
return self.dehydrate_related(fk_bundle, self.fk_resource, for_list=for_list)

def hydrate(self, bundle):
value = super(ToOneField, self).hydrate(bundle)
Expand Down Expand Up @@ -774,7 +774,7 @@ def __init__(self, to, attribute, related_name=None, default=NOT_PROVIDED,
)
self.m2m_bundles = []

def dehydrate(self, bundle):
def dehydrate(self, bundle, for_list=True):
if not bundle.obj or not bundle.obj.pk:
if not self.null:
raise ApiFieldError("The model '%r' does not have a primary key and can not be used in a ToMany context." % bundle.obj)
Expand Down Expand Up @@ -817,7 +817,7 @@ def dehydrate(self, bundle):
m2m_resource = self.get_related_resource(m2m)
m2m_bundle = Bundle(obj=m2m, request=bundle.request)
self.m2m_resources.append(m2m_resource)
m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource))
m2m_dehydrated.append(self.dehydrate_related(m2m_bundle, m2m_resource, for_list=for_list))

return m2m_dehydrated

Expand Down Expand Up @@ -873,7 +873,7 @@ class TimeField(ApiField):
dehydrated_type = 'time'
help_text = 'A time as string. Ex: "20:05:23"'

def dehydrate(self, obj):
def dehydrate(self, obj, for_list=True):
return self.convert(super(TimeField, self).dehydrate(obj))

def convert(self, value):
Expand Down
2 changes: 1 addition & 1 deletion tastypie/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ def full_dehydrate(self, bundle, for_list=False):
field_object.api_name = self._meta.api_name
field_object.resource_name = self._meta.resource_name

bundle.data[field_name] = field_object.dehydrate(bundle)
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)
Expand Down
8 changes: 4 additions & 4 deletions tests/core/tests/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ def test_dehydrate_full_detail_list(self):
#list path with full_detail=False
request.path = "/api/v1/notes/1/"
field_1 = ToOneField(UserResource, 'author', full=True, full_detail=False)
self.assertEqual(field_1.dehydrate(bundle), '/api/v1/users/1/')
self.assertEqual(field_1.dehydrate(bundle, for_list=False), '/api/v1/users/1/')

def test_hydrate(self):
note = Note()
Expand Down Expand Up @@ -1090,7 +1090,7 @@ def test_dehydrate_full_detail_list(self):
request = MockRequest()
request.path = "/api/v1/subjects/%(pk)s/" % {'pk': self.note_1.pk}
bundle_1 = Bundle(obj=self.note_1, request=request)
self.assertEqual(field_1.dehydrate(bundle_1), ['/api/v1/subjects/1/', '/api/v1/subjects/2/'])
self.assertEqual(field_1.dehydrate(bundle_1, for_list=False), ['/api/v1/subjects/1/', '/api/v1/subjects/2/'])

#list path with full_detail=False
field_2 = ToManyField(SubjectResource, 'subjects', full=True, full_detail=False)
Expand Down Expand Up @@ -1125,7 +1125,7 @@ def test_dehydrate_full_detail_list(self):
request = MockRequest()
request.path = "/api/v1/subjects/%(pk)s/" % {'pk': self.note_1.pk}
bundle_4 = Bundle(obj=self.note_1, request=request)
subject_bundle_list = field_4.dehydrate(bundle_4)
subject_bundle_list = field_4.dehydrate(bundle_4, for_list=False)
self.assertEqual(len(subject_bundle_list), 2)
self.assertEqual(isinstance(subject_bundle_list[0], Bundle), True)
self.assertEqual(subject_bundle_list[0].data['name'], u'News')
Expand Down Expand Up @@ -1190,7 +1190,7 @@ def test_dehydrate_full_detail_list(self):
request = MockRequest()
request.path = "/api/v1/subjects/%(pk)s/" % {'pk': self.note_1.pk}
bundle_8 = Bundle(obj=self.note_1, request=request)
self.assertEqual(field_8.dehydrate(bundle_8), ['/api/v1/subjects/1/', '/api/v1/subjects/2/'])
self.assertEqual(field_8.dehydrate(bundle_8, for_list=False), ['/api/v1/subjects/1/', '/api/v1/subjects/2/'])

#detail url with full_detail=True and get parameters
field_9 = ToManyField(SubjectResource, 'subjects', full=True, full_detail=True)
Expand Down
2 changes: 0 additions & 2 deletions tests/related_resource/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@ def test_one_to_many(self):
pk = Person.objects.all()[0].pk
request = MockRequest()
request.method = 'GET'
request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
resp = pr.get_detail(request, pk=pk)
self.assertEqual(resp.status_code, 200)

Expand All @@ -375,7 +374,6 @@ def test_one_to_many(self):
request = MockRequest()
request.GET = {'format': 'json'}
request.method = 'PUT'
request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
setattr(request, self.body_attr, json.dumps(person))
resp = pr.put_detail(request, pk=pk)
self.assertEqual(resp.status_code, 204)
Expand Down

0 comments on commit 01e620a

Please sign in to comment.