Commit c18fb0d6 by Tom Christie

Added a `post_save` hook. Closes #558.

parent 123c6cbc
...@@ -131,6 +131,15 @@ Each of the generic views provided is built by combining one of the base views b ...@@ -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. 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**: **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. * `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.
......
...@@ -28,6 +28,7 @@ You can determine your currently installed version using `pip freeze`: ...@@ -28,6 +28,7 @@ You can determine your currently installed version using `pip freeze`:
### Master ### Master
* Added a `post_save()` hook to the generic views.
* Bugfix: Fix styling on browsable API login. * Bugfix: Fix styling on browsable API login.
* Bugfix: Fix issue with deserializing empty to-many relations. * 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. * Bugfix: Ensure model field validation is still applied for ModelSerializer subclasses with an custom `.restore_object()` method.
......
...@@ -48,7 +48,7 @@ class GenericAPIView(views.APIView): ...@@ -48,7 +48,7 @@ class GenericAPIView(views.APIView):
return serializer_class return serializer_class
def get_serializer(self, instance=None, data=None, 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 Return the serializer instance that should be used for validating and
deserializing input, and for serializing output. deserializing input, and for serializing output.
...@@ -58,6 +58,20 @@ class GenericAPIView(views.APIView): ...@@ -58,6 +58,20 @@ class GenericAPIView(views.APIView):
return serializer_class(instance, data=data, files=files, return serializer_class(instance, data=data, files=files,
many=many, partial=partial, context=context) 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): class MultipleObjectAPIView(MultipleObjectMixin, GenericAPIView):
""" """
......
...@@ -22,6 +22,7 @@ class CreateModelMixin(object): ...@@ -22,6 +22,7 @@ class CreateModelMixin(object):
if serializer.is_valid(): if serializer.is_valid():
self.pre_save(serializer.object) self.pre_save(serializer.object)
self.object = serializer.save() self.object = serializer.save()
self.post_save(self.object, created=True)
headers = self.get_success_headers(serializer.data) headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers) headers=headers)
...@@ -34,9 +35,6 @@ class CreateModelMixin(object): ...@@ -34,9 +35,6 @@ class CreateModelMixin(object):
except (TypeError, KeyError): except (TypeError, KeyError):
return {} return {}
def pre_save(self, obj):
pass
class ListModelMixin(object): class ListModelMixin(object):
""" """
...@@ -88,12 +86,15 @@ class UpdateModelMixin(object): ...@@ -88,12 +86,15 @@ class UpdateModelMixin(object):
""" """
def update(self, request, *args, **kwargs): def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False) partial = kwargs.pop('partial', False)
self.object = None
try: try:
self.object = self.get_object() self.object = self.get_object()
success_status_code = status.HTTP_200_OK
except Http404: except Http404:
self.object = None created = True
success_status_code = status.HTTP_201_CREATED 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, serializer = self.get_serializer(self.object, data=request.DATA,
files=request.FILES, partial=partial) files=request.FILES, partial=partial)
...@@ -101,6 +102,7 @@ class UpdateModelMixin(object): ...@@ -101,6 +102,7 @@ class UpdateModelMixin(object):
if serializer.is_valid(): if serializer.is_valid():
self.pre_save(serializer.object) self.pre_save(serializer.object)
self.object = serializer.save() self.object = serializer.save()
self.post_save(self.object, created=created)
return Response(serializer.data, status=success_status_code) return Response(serializer.data, status=success_status_code)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment