aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2013-02-06 21:28:03 +0000
committerTom Christie2013-02-06 21:28:03 +0000
commitc18fb0d6953940f63cd8747a5ce543d31999996f (patch)
tree08915d4cf65b22ed24483f7371a36d1cd96d6482
parent123c6cbc7cebf797ed0b310a5a8d398fa6323ce4 (diff)
downloaddjango-rest-framework-c18fb0d6953940f63cd8747a5ce543d31999996f.tar.bz2
Added a `post_save` hook. Closes #558.
-rw-r--r--docs/api-guide/generic-views.md9
-rw-r--r--docs/topics/release-notes.md1
-rw-r--r--rest_framework/generics.py16
-rw-r--r--rest_framework/mixins.py12
4 files changed, 32 insertions, 6 deletions
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 693e210d..20f1be63 100644
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -131,6 +131,15 @@ Each of the generic views provided is built by combining one of the base views b
Extends REST framework's `APIView` class, adding support for serialization of model instances and model querysets.
+**Methods**:
+
+* `get_serializer_context(self)` - Returns a dictionary containing any extra context that should be supplied to the serializer. Defaults to including `'request'`, `'view'` and `'format'` keys.
+* `get_serializer_class(self)` - Returns the class that should be used for the serializer.
+* `get_serializer(self, instance=None, data=None, files=None, many=False, partial=False)` - Returns a serializer instance.
+* `pre_save(self, obj)` - A hook that is called before saving an object.
+* `post_save(self, obj, created=False)` - A hook that is called after saving an object.
+
+
**Attributes**:
* `model` - The model that should be used for this view. Used as a fallback for determining the serializer if `serializer_class` is not set, and as a fallback for determining the queryset if `queryset` is not set. Otherwise not required.
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 70c915b7..d5f060e7 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -28,6 +28,7 @@ You can determine your currently installed version using `pip freeze`:
### Master
+* Added a `post_save()` hook to the generic views.
* Bugfix: Fix styling on browsable API login.
* Bugfix: Fix issue with deserializing empty to-many relations.
* Bugfix: Ensure model field validation is still applied for ModelSerializer subclasses with an custom `.restore_object()` method.
diff --git a/rest_framework/generics.py b/rest_framework/generics.py
index 34e32da3..5abb915b 100644
--- a/rest_framework/generics.py
+++ b/rest_framework/generics.py
@@ -48,7 +48,7 @@ class GenericAPIView(views.APIView):
return serializer_class
def get_serializer(self, instance=None, data=None,
- files=None, partial=False, many=False):
+ files=None, many=False, partial=False):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
@@ -58,6 +58,20 @@ class GenericAPIView(views.APIView):
return serializer_class(instance, data=data, files=files,
many=many, partial=partial, context=context)
+ def pre_save(self, obj):
+ """
+ Placeholder method for calling before saving an object.
+ May be used eg. to set attributes on the object that are implicit
+ in either the request, or the url.
+ """
+ pass
+
+ def post_save(self, obj, created=False):
+ """
+ Placeholder method for calling after saving an object.
+ """
+ pass
+
class MultipleObjectAPIView(MultipleObjectMixin, GenericAPIView):
"""
diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py
index 73a3d200..61ac225b 100644
--- a/rest_framework/mixins.py
+++ b/rest_framework/mixins.py
@@ -22,6 +22,7 @@ class CreateModelMixin(object):
if serializer.is_valid():
self.pre_save(serializer.object)
self.object = serializer.save()
+ self.post_save(self.object, created=True)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)
@@ -34,9 +35,6 @@ class CreateModelMixin(object):
except (TypeError, KeyError):
return {}
- def pre_save(self, obj):
- pass
-
class ListModelMixin(object):
"""
@@ -88,12 +86,15 @@ class UpdateModelMixin(object):
"""
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
+ self.object = None
try:
self.object = self.get_object()
- success_status_code = status.HTTP_200_OK
except Http404:
- self.object = None
+ created = True
success_status_code = status.HTTP_201_CREATED
+ else:
+ created = False
+ success_status_code = status.HTTP_200_OK
serializer = self.get_serializer(self.object, data=request.DATA,
files=request.FILES, partial=partial)
@@ -101,6 +102,7 @@ class UpdateModelMixin(object):
if serializer.is_valid():
self.pre_save(serializer.object)
self.object = serializer.save()
+ self.post_save(self.object, created=created)
return Response(serializer.data, status=success_status_code)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)