Added a post_save hook. Closes #558.

This commit is contained in:
Tom Christie 2013-02-06 21:28:03 +00:00
parent 123c6cbc7c
commit c18fb0d695
4 changed files with 32 additions and 6 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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):
"""

View File

@ -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)