Skip to content

Instantly share code, notes, and snippets.

@teeberg
Last active February 11, 2016 16:03
Show Gist options
  • Select an option

  • Save teeberg/87463ed0cd4dc4ceba6b to your computer and use it in GitHub Desktop.

Select an option

Save teeberg/87463ed0cd4dc4ceba6b to your computer and use it in GitHub Desktop.
Fix resource URI creation when using same model in several API versions (django-tastypie)
commit 48f79ade1acdc5683be9aff1c4cbfe83724c0a67
Author: Jonas Trappenberg <[email protected]>
Date: Tue Apr 22 11:32:03 2014 -0700
Fix URL resolution.
diff --git a/tastypie/api.py b/tastypie/api.py
index d8788af..5373f30 100644
--- a/tastypie/api.py
+++ b/tastypie/api.py
@@ -48,10 +48,6 @@ class Api(object):
warnings.warn("A new resource '%r' is replacing the existing canonical URL for '%s'." % (resource, resource_name), Warning, stacklevel=2)
self._canonicals[resource_name] = resource
- # TODO: This is messy, but makes URI resolution on FK/M2M fields
- # work consistently.
- resource._meta.api_name = self.api_name
- resource.__class__.Meta.api_name = self.api_name
def unregister(self, resource_name):
"""
diff --git a/tastypie/contrib/contenttypes/resources.py b/tastypie/contrib/contenttypes/resources.py
index aa70ca6..7d86bfa 100644
--- a/tastypie/contrib/contenttypes/resources.py
+++ b/tastypie/contrib/contenttypes/resources.py
@@ -36,7 +36,7 @@ class GenericResource(ModelResource):
except (Resolver404, KeyError):
raise NotFound("The URL provided '%s' was not a link to a valid resource." % uri)
- parent_resource = resource_class(api_name=self._meta.api_name)
+ parent_resource = resource_class(api_name=self.api_name)
kwargs = parent_resource.remove_api_resource_names(kwargs)
bundle = Bundle(request=request)
return parent_resource.obj_get(bundle, **kwargs)
diff --git a/tastypie/fields.py b/tastypie/fields.py
index bdbb36a..ae3f291 100644
--- a/tastypie/fields.py
+++ b/tastypie/fields.py
@@ -509,12 +509,12 @@ class RelatedField(ApiField):
"""
Instaniates the related resource.
"""
- related_resource = self.to_class()
+ related_resource = self.to_class(api_name=self.api_name)
# Fix the ``api_name`` if it's not present.
- if related_resource._meta.api_name is None:
- if self._resource and not self._resource._meta.api_name is None:
- related_resource._meta.api_name = self._resource._meta.api_name
+ if related_resource.api_name is None:
+ if self._resource and not self._resource.api_name is None:
+ related_resource.api_name = self._resource.api_name
# Try to be efficient about DB queries.
related_resource.instance = related_instance
diff --git a/tastypie/resources.py b/tastypie/resources.py
index 0da585b..0d51a3a 100644
--- a/tastypie/resources.py
+++ b/tastypie/resources.py
@@ -170,9 +170,7 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
"""
def __init__(self, api_name=None):
self.fields = deepcopy(self.base_fields)
-
- if not api_name is None:
- self._meta.api_name = api_name
+ self.api_name = api_name
def __getattr__(self, name):
if name in self.fields:
@@ -749,11 +747,9 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
"""
kwargs = {
'resource_name': self._meta.resource_name,
+ 'api_name': self.api_name,
}
- if self._meta.api_name is not None:
- kwargs['api_name'] = self._meta.api_name
-
if bundle_or_obj is not None:
kwargs.update(self.detail_uri_kwargs(bundle_or_obj))
@@ -826,7 +822,7 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
# 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.api_name = self.api_name
field_object.resource_name = self._meta.resource_name
bundle.data[field_name] = field_object.dehydrate(bundle, for_list=for_list)
@@ -1007,7 +1003,7 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
smooshed.append("%s=%s" % (key, value))
# Use a list plus a ``.join()`` because it's faster than concatenation.
- return "%s:%s:%s:%s" % (self._meta.api_name, self._meta.resource_name, ':'.join(args), ':'.join(sorted(smooshed)))
+ return "%s:%s:%s:%s" % (self.api_name, self._meta.resource_name, ':'.join(args), ':'.join(sorted(smooshed)))
# Data access methods.
diff --git a/tests/basic/tests/resources.py b/tests/basic/tests/resources.py
index f9d5157..3cdb1d2 100644
--- a/tests/basic/tests/resources.py
+++ b/tests/basic/tests/resources.py
@@ -25,9 +25,11 @@ class NoPathLazyUserResource(ModelResource):
class LazyUserResource(ModelResource):
notes = ToManyField('basic.tests.resources.NoteResource', 'notes')
+ def __init__(self):
+ super(LazyUserResource, self).__init__(api_name='foo')
+
class Meta:
queryset = User.objects.all()
- api_name = 'foo'
class NoteResource(ModelResource):
@@ -85,7 +87,7 @@ class NoteModelResourceTestCase(TestCase):
# reversals will fail. Fakes the instance as ``None``, since for
# testing purposes, we don't care.
related = lur.notes.get_related_resource(None)
- self.assertEqual(related._meta.api_name, 'foo')
+ self.assertEqual(related.api_name, 'foo')
class AnnotatedNoteModelResourceTestCase(TestCase):
diff --git a/tests/related_resource/tests.py b/tests/related_resource/tests.py
index f756456..c12ac3e 100644
--- a/tests/related_resource/tests.py
+++ b/tests/related_resource/tests.py
@@ -320,7 +320,7 @@ class NestedRelatedResourceTest(TestCase):
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})
+ request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr.api_name})
resp = pr.get_detail(request, pk=pk)
self.assertEqual(resp.status_code, 200)
@@ -336,7 +336,7 @@ class NestedRelatedResourceTest(TestCase):
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})
+ request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr.api_name})
request.set_body(resp.content.decode('utf-8'))
resp = pr.put_detail(request, pk=pk)
self.assertEqual(resp.status_code, 204)
@@ -431,7 +431,7 @@ class NestedRelatedResourceTest(TestCase):
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})
+ request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr.api_name})
resp = pr.get_detail(request, pk=pk)
self.assertEqual(resp.status_code, 200)
@@ -449,7 +449,7 @@ class NestedRelatedResourceTest(TestCase):
request.GET = {'format': 'json'}
request.method = 'PUT'
request.set_body(json.dumps(person))
- request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
+ request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr.api_name})
resp = pr.put_detail(request, pk=pk)
self.assertEqual(resp.status_code, 204)
@@ -480,7 +480,7 @@ class NestedRelatedResourceTest(TestCase):
request = MockRequest()
request.GET = {'format': 'json'}
request.method = 'POST'
- request.path = reverse('api_dispatch_list', kwargs={'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
+ request.path = reverse('api_dispatch_list', kwargs={'resource_name': pr._meta.resource_name, 'api_name': pr.api_name})
request.set_body(json.dumps(data))
resp = pr.post_list(request)
self.assertEqual(resp.status_code, 201)
@@ -491,7 +491,7 @@ class NestedRelatedResourceTest(TestCase):
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})
+ request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr.api_name})
resp = pr.get_detail(request, pk=pk)
self.assertEqual(resp.status_code, 200)
@@ -510,7 +510,7 @@ class NestedRelatedResourceTest(TestCase):
request.GET = {'format': 'json'}
request.method = 'PUT'
request.set_body(json.dumps(person))
- request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
+ request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr.api_name})
resp = pr.put_detail(request, pk=pk)
self.assertEqual(resp.status_code, 204)
@@ -521,7 +521,7 @@ class NestedRelatedResourceTest(TestCase):
person['dogs'][0]['bones'][0]['color'] = 'gray'
body = json.dumps(person)
request.set_body(body)
- request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
+ request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr.api_name})
resp = pr.put_detail(request, pk=pk)
self.assertEqual(resp.status_code, 204)
@@ -626,7 +626,7 @@ class RelatedSaveCallsTest(TestCase):
request.path = reverse('api_dispatch_detail', kwargs={'pk': tag.pk,
'resource_name': resource._meta.resource_name,
- 'api_name': resource._meta.api_name})
+ 'api_name': resource.api_name})
resource.put_detail(request)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment