mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-09 15:52:29 +03:00
Add a method to cache the model mixin.
- Specifically can cache the instance on a read, update, or delete operation. - Also adds a get_instance_or_404 method - Useful for retrieving the instance from a permission class without doing extra queries
This commit is contained in:
parent
239d8c6c4d
commit
912a897e2d
|
@ -504,12 +504,6 @@ class ModelMixin(object):
|
||||||
|
|
||||||
return all_kw_args
|
return all_kw_args
|
||||||
|
|
||||||
def get_instance(self, **kwargs):
|
|
||||||
"""
|
|
||||||
Get a model instance for read/update/delete requests.
|
|
||||||
"""
|
|
||||||
return self.get_queryset().get(**kwargs)
|
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""
|
"""
|
||||||
Return the queryset for this view.
|
Return the queryset for this view.
|
||||||
|
@ -524,20 +518,34 @@ class ModelMixin(object):
|
||||||
return getattr(self.resource, 'ordering', None)
|
return getattr(self.resource, 'ordering', None)
|
||||||
|
|
||||||
|
|
||||||
class ReadModelMixin(ModelMixin):
|
class ExistingInstanceMixin (object):
|
||||||
|
"""
|
||||||
|
Assume a single instance for the view. Caches the instance object on self.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_instance(self):
|
||||||
|
if not hasattr(self, 'model_instance'):
|
||||||
|
query_kwargs = self.get_query_kwargs(
|
||||||
|
self.request, *self.args, **self.kwargs)
|
||||||
|
self.model_instance = self.get_queryset().get(**query_kwargs)
|
||||||
|
return self.model_instance
|
||||||
|
|
||||||
|
def get_instance_or_404(self):
|
||||||
|
model = self.resource.model
|
||||||
|
|
||||||
|
try:
|
||||||
|
return self.get_instance()
|
||||||
|
except model.DoesNotExist:
|
||||||
|
raise ErrorResponse(status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
|
||||||
|
class ReadModelMixin(ModelMixin, ExistingInstanceMixin):
|
||||||
"""
|
"""
|
||||||
Behavior to read a `model` instance on GET requests
|
Behavior to read a `model` instance on GET requests
|
||||||
"""
|
"""
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
model = self.resource.model
|
instance = self.get_instance_or_404()
|
||||||
query_kwargs = self.get_query_kwargs(request, *args, **kwargs)
|
return instance
|
||||||
|
|
||||||
try:
|
|
||||||
self.model_instance = self.get_instance(**query_kwargs)
|
|
||||||
except model.DoesNotExist:
|
|
||||||
raise ErrorResponse(status.HTTP_404_NOT_FOUND)
|
|
||||||
|
|
||||||
return self.model_instance
|
|
||||||
|
|
||||||
|
|
||||||
class CreateModelMixin(ModelMixin):
|
class CreateModelMixin(ModelMixin):
|
||||||
|
@ -580,18 +588,17 @@ class CreateModelMixin(ModelMixin):
|
||||||
return Response(status.HTTP_201_CREATED, instance, headers)
|
return Response(status.HTTP_201_CREATED, instance, headers)
|
||||||
|
|
||||||
|
|
||||||
class UpdateModelMixin(ModelMixin):
|
class UpdateModelMixin(ModelMixin, ExistingInstanceMixin):
|
||||||
"""
|
"""
|
||||||
Behavior to update a `model` instance on PUT requests
|
Behavior to update a `model` instance on PUT requests
|
||||||
"""
|
"""
|
||||||
def put(self, request, *args, **kwargs):
|
def put(self, request, *args, **kwargs):
|
||||||
model = self.resource.model
|
model = self.resource.model
|
||||||
query_kwargs = self.get_query_kwargs(request, *args, **kwargs)
|
|
||||||
|
|
||||||
# TODO: update on the url of a non-existing resource url doesn't work
|
# TODO: update on the url of a non-existing resource url doesn't work
|
||||||
# correctly at the moment - will end up with a new url
|
# correctly at the moment - will end up with a new url
|
||||||
try:
|
try:
|
||||||
self.model_instance = self.get_instance(**query_kwargs)
|
self.model_instance = self.get_instance()
|
||||||
|
|
||||||
for (key, val) in self.CONTENT.items():
|
for (key, val) in self.CONTENT.items():
|
||||||
setattr(self.model_instance, key, val)
|
setattr(self.model_instance, key, val)
|
||||||
|
@ -601,19 +608,12 @@ class UpdateModelMixin(ModelMixin):
|
||||||
return self.model_instance
|
return self.model_instance
|
||||||
|
|
||||||
|
|
||||||
class DeleteModelMixin(ModelMixin):
|
class DeleteModelMixin(ModelMixin, ExistingInstanceMixin):
|
||||||
"""
|
"""
|
||||||
Behavior to delete a `model` instance on DELETE requests
|
Behavior to delete a `model` instance on DELETE requests
|
||||||
"""
|
"""
|
||||||
def delete(self, request, *args, **kwargs):
|
def delete(self, request, *args, **kwargs):
|
||||||
model = self.resource.model
|
instance = self.get_instance_or_404()
|
||||||
query_kwargs = self.get_query_kwargs(request, *args, **kwargs)
|
|
||||||
|
|
||||||
try:
|
|
||||||
instance = self.get_instance(**query_kwargs)
|
|
||||||
except model.DoesNotExist:
|
|
||||||
raise ErrorResponse(status.HTTP_404_NOT_FOUND, None, {})
|
|
||||||
|
|
||||||
instance.delete()
|
instance.delete()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,10 @@ class TestModelRead(TestModelsTestCase):
|
||||||
mixin = ReadModelMixin()
|
mixin = ReadModelMixin()
|
||||||
mixin.resource = GroupResource
|
mixin.resource = GroupResource
|
||||||
|
|
||||||
|
mixin.request = request
|
||||||
|
mixin.args = ()
|
||||||
|
mixin.kwargs = {'id': group.id}
|
||||||
|
|
||||||
response = mixin.get(request, id=group.id)
|
response = mixin.get(request, id=group.id)
|
||||||
self.assertEquals(group.name, response.name)
|
self.assertEquals(group.name, response.name)
|
||||||
|
|
||||||
|
@ -41,6 +45,10 @@ class TestModelRead(TestModelsTestCase):
|
||||||
mixin = ReadModelMixin()
|
mixin = ReadModelMixin()
|
||||||
mixin.resource = GroupResource
|
mixin.resource = GroupResource
|
||||||
|
|
||||||
|
mixin.request = request
|
||||||
|
mixin.args = ()
|
||||||
|
mixin.kwargs = {'id': 12345}
|
||||||
|
|
||||||
self.assertRaises(ErrorResponse, mixin.get, request, id=12345)
|
self.assertRaises(ErrorResponse, mixin.get, request, id=12345)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user