made changes requested by Tom. In resources : removed decorators, and 'request' parameter from the crud methods

This commit is contained in:
Sébastien Piquemal 2012-01-09 20:00:18 +02:00
parent d1c217523b
commit 3a52c213f9
4 changed files with 67 additions and 51 deletions

View File

@ -471,12 +471,21 @@ class ResourceMixin(object):
"""
return self.deserialize(self.request.GET)
@property
def resource(self):
if not hasattr(self, '_resource'):
self._resource = self.resource_class(view=self)
return self._resource
def get_resource_class(self):
if self.resource_class:
return self.resource_class
elif getattr(self, 'model', None):
return ModelResource
elif getattr(self, 'form', None):
return FormResource
elif hasattr(self, 'request') and getattr(self, '%s_form' % self.method.lower(), None):
return FormResource
else:
return Resource
def get_resource(self):
resource_class = self.get_resource_class()
return resource_class(view=self)
@ -496,6 +505,7 @@ class InstanceMixin(object):
associated with this view.
"""
view = super(InstanceMixin, cls).as_view(**initkwargs)
# TODO: FIX !!! Very bad now, since this is attached on the class (thread-safety)
resource_class = getattr(cls(**initkwargs), 'resource_class', None)
if resource_class:
# We do a little dance when we store the view callable...
@ -512,51 +522,55 @@ class InstanceMixin(object):
class GetResourceMixin(object):
def get(self, request, *args, **kwargs):
resource = self.get_resource()
try:
self.resource.retrieve(request, *args, **kwargs)
except self.resource.DoesNotExist:
resource.retrieve(*args, **kwargs)
except resource.DoesNotExist:
raise ErrorResponse(status.HTTP_404_NOT_FOUND)
return self.resource.instance
return resource.instance
class PostResourceMixin(object):
def post(self, request, *args, **kwargs):
self.resource.create(request, *args, **kwargs)
self.resource.update(self.CONTENT, request, *args, **kwargs)
headers = {'Location': self.resource.get_url()}
return Response(status.HTTP_201_CREATED, self.resource.instance, headers)
resource = self.get_resource()
resource.create(*args, **kwargs)
resource.update(self.CONTENT, *args, **kwargs)
headers = {'Location': resource.get_url()}
return Response(status.HTTP_201_CREATED, resource.instance, headers)
class PutResourceMixin(object):
def put(self, request, *args, **kwargs):
headers = {}
resource = self.get_resource()
try:
self.resource.retrieve(request, *args, **kwargs)
resource.retrieve(*args, **kwargs)
status_code = status.HTTP_204_NO_CONTENT
except self.resource.DoesNotExist:
self.resource.create(request, *args, **kwargs)
except resource.DoesNotExist:
resource.create(*args, **kwargs)
status_code = status.HTTP_201_CREATED
self.resource.update(self.CONTENT, request, *args, **kwargs)
return Response(status_code, self.resource.instance, {})
resource.update(self.CONTENT, *args, **kwargs)
return Response(status_code, resource.instance, {})
class DeleteResourceMixin(object):
def delete(self, request, *args, **kwargs):
resource = self.get_resource()
try:
self.resource.retrieve(request, *args, **kwargs)
except self.resource.DoesNotExist:
resource.retrieve(*args, **kwargs)
except resource.DoesNotExist:
raise ErrorResponse(status.HTTP_404_NOT_FOUND)
self.resource.delete(request, *args, **kwargs)
resource.delete(*args, **kwargs)
return
class ListResourceMixin(object):
def get(self, request, *args, **kwargs):
return self.resource.list(request, *args, **kwargs)
resource = self.get_resource()
return resource.list(*args, **kwargs)
########## Pagination Mixins ##########

View File

@ -216,4 +216,4 @@ class PerResourceThrottling(BaseThrottle):
"""
def get_cache_key(self):
return 'throttle_resource_%s' % self.view.resource.__class__.__name__
return 'throttle_resource_%s' % self.view.get_resource_class().__name__

View File

@ -6,14 +6,6 @@ from djangorestframework.response import ErrorResponse
from djangorestframework.serializer import Serializer, _SkipField
def bound_resource_required(meth):
def _decorated(self, *args, **kwargs):
if not self.is_bound():
raise Exception("resource needs to be bound") #TODO: what exception?
return meth(self, *args, **kwargs)
return _decorated
class BaseResource(Serializer):
"""
Base class for all Resource classes, which simply defines the interface
@ -26,7 +18,8 @@ class BaseResource(Serializer):
# TODO: Inheritance, like for models
class DoesNotExist(Exception): pass
def __init__(self, instance=None, view=None, depth=None, stack=[], **kwargs):
# !!! `view` should be first kwarg to avoid backward incompatibilities. (lol)
def __init__(self, view=None, instance=None, depth=None, stack=[], **kwargs):
super(BaseResource, self).__init__(depth, stack, **kwargs)
self.view = view
self.instance = instance
@ -39,21 +32,18 @@ class BaseResource(Serializer):
"""
return data
def retrieve(self, request, *args, **kwargs):
def retrieve(self, *args, **kwargs):
raise NotImplementedError()
def create(self, request, *args, **kwargs):
def create(self, *args, **kwargs):
raise NotImplementedError()
@bound_resource_required
def update(self, data, request, *args, **kwargs):
def update(self, data, *args, **kwargs):
raise NotImplementedError()
@bound_resource_required
def delete(self, request, *args, **kwargs):
def delete(self, *args, **kwargs):
raise NotImplementedError()
@bound_resource_required
def get_url(self):
raise NotImplementedError()
@ -148,7 +138,8 @@ class FormResource(Resource):
if bound_form is None:
return data
self.view.bound_form_instance = bound_form
if self.view is not None:
self.view.bound_form_instance = bound_form
data = data and data or {}
files = files and files or {}
@ -314,17 +305,17 @@ class ModelResource(FormResource):
is not set.
"""
def __init__(self, instance=None, view=None, depth=None, stack=[], **kwargs):
def __init__(self, view=None, instance=None, depth=None, stack=[], **kwargs):
"""
Allow :attr:`form` and :attr:`model` attributes set on the
:class:`View` to override the :attr:`form` and :attr:`model`
attributes set on the :class:`Resource`.
"""
super(ModelResource, self).__init__(instance=instance, view=view, depth=depth, stack=stack, **kwargs)
super(ModelResource, self).__init__(view=None, instance=instance, depth=depth, stack=stack, **kwargs)
self.model = getattr(view, 'model', None) or self.model
def retrieve(self, request, *args, **kwargs):
def retrieve(self, *args, **kwargs):
"""
Return a model instance or None.
"""
@ -339,7 +330,7 @@ class ModelResource(FormResource):
self.instance = instance
return self.instance
def create(self, request, *args, **kwargs):
def create(self, *args, **kwargs):
model = self.get_model()
kwargs = self._clean_url_kwargs(kwargs)
@ -347,8 +338,12 @@ class ModelResource(FormResource):
self.instance.save()
return self.instance
@bound_resource_required
def update(self, data, request, *args, **kwargs):
def update(self, data, *args, **kwargs):
# The resource needs to be bound to an
# instance, or updating is not possible
if not self.is_bound():
raise Exception("resource needs to be bound") #TODO: what exception?
model = self.get_model()
kwargs = self._clean_url_kwargs(kwargs)
data = dict(data, **kwargs)
@ -382,12 +377,16 @@ class ModelResource(FormResource):
self.instance.save()
return self.instance
@bound_resource_required
def delete(self, request, *args, **kwargs):
def delete(self, *args, **kwargs):
# The resource needs to be bound to an
# instance, or deleting is not possible
if not self.is_bound():
raise Exception("resource needs to be bound") #TODO: what exception?
self.instance.delete()
return self.instance
def list(self, request, *args, **kwargs):
def list(self, *args, **kwargs):
# TODO: QuerysetResource instead !?
kwargs = self._clean_url_kwargs(kwargs)
queryset = self.get_queryset()
@ -397,7 +396,6 @@ class ModelResource(FormResource):
queryset = queryset.order_by(ordering)
return queryset.filter(**kwargs)
@bound_resource_required
def get_url(self):
"""
Attempts to reverse resolve the url of the given model *instance* for
@ -409,6 +407,10 @@ class ModelResource(FormResource):
This method can be overridden if you need to set the resource url
reversing explicitly.
"""
# The resource needs to be bound to an
# instance, or getting url is not possible
if not self.is_bound():
raise Exception("resource needs to be bound") #TODO: what exception?
if not hasattr(self, 'view_callable'):
raise _SkipField

View File

@ -157,7 +157,7 @@ class RendererIntegrationTests(TestCase):
_flat_repr = '{"foo": ["bar", "baz"]}'
_indented_repr = '{\n "foo": [\n "bar", \n "baz"\n ]\n}'
_indented_repr = '{\n "foo": [\n "bar",\n "baz"\n ]\n}'
class JSONRendererTests(TestCase):