aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/api-guide/fields.md2
-rwxr-xr-xdocs/api-guide/generic-views.md4
-rw-r--r--docs/api-guide/renderers.md4
-rw-r--r--docs/topics/release-notes.md1
-rw-r--r--rest_framework/fields.py2
-rw-r--r--rest_framework/generics.py12
-rw-r--r--rest_framework/mixins.py2
7 files changed, 22 insertions, 5 deletions
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index 03c5af32..e05c0306 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -286,7 +286,7 @@ An image representation.
Corresponds to `django.forms.fields.ImageField`.
-Requires the `PIL` package.
+Requires either the `Pillow` package or `PIL` package. The `Pillow` package is recommended, as `PIL` is no longer actively maintained.
Signature and validation is the same as with `FileField`.
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index b9242724..83c3e45f 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -163,12 +163,14 @@ For example:
return 20
return 100
-**Save hooks**:
+**Save / deletion hooks**:
The following methods are provided as placeholder interfaces. They contain empty implementations and are not called directly by `GenericAPIView`, but they are overridden and used by some of the mixin classes.
* `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.
+* `pre_delete(self, obj)` - A hook that is called before deleting an object.
+* `post_delete(self, obj)` - A hook that is called after deleting an object.
The `pre_save` method in particular is a useful hook for setting attributes that are implicit in the request, but are not part of the request data. For instance, you might set an attribute on the object based on the request user, or based on a URL keyword argument.
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index 858e2f07..f30fa26a 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -167,14 +167,14 @@ The template name is determined by (in order of preference):
An example of a view that uses `TemplateHTMLRenderer`:
- class UserDetail(generics.RetrieveUserAPIView):
+ class UserDetail(generics.RetrieveAPIView):
"""
A view that returns a templated HTML representations of a given user.
"""
queryset = User.objects.all()
renderer_classes = (TemplateHTMLRenderer,)
- def get(self, request, *args, **kwargs)
+ def get(self, request, *args, **kwargs):
self.object = self.get_object()
return Response({'user': self.object}, template_name='user_detail.html')
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 0759bd9d..c7e24a5e 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -42,6 +42,7 @@ You can determine your currently installed version using `pip freeze`:
### Master
+* Added `pre_delete()` and `post_delete()` method hooks.
* Bugfix: Correctly handle validation errors in PUT-as-create case, responding with 400.
### 2.3.9
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 0fca718e..5a4f04a5 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -971,7 +971,7 @@ class ImageField(FileField):
return None
from rest_framework.compat import Image
- assert Image is not None, 'PIL must be installed for ImageField support'
+ assert Image is not None, 'Either Pillow or PIL must be installed for ImageField support.'
# We need to get a file object for PIL. We might have a path or we might
# have to read the data into memory.
diff --git a/rest_framework/generics.py b/rest_framework/generics.py
index 7cb80a84..fd411ad3 100644
--- a/rest_framework/generics.py
+++ b/rest_framework/generics.py
@@ -344,6 +344,18 @@ class GenericAPIView(views.APIView):
"""
pass
+ def pre_delete(self, obj):
+ """
+ Placeholder method for calling before deleting an object.
+ """
+ pass
+
+ def post_delete(self, obj):
+ """
+ Placeholder method for calling after saving an object.
+ """
+ pass
+
def metadata(self, request):
"""
Return a dictionary of metadata about the view.
diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py
index 79f79c30..43950c4b 100644
--- a/rest_framework/mixins.py
+++ b/rest_framework/mixins.py
@@ -192,5 +192,7 @@ class DestroyModelMixin(object):
"""
def destroy(self, request, *args, **kwargs):
obj = self.get_object()
+ self.pre_delete(obj)
obj.delete()
+ self.post_delete(obj)
return Response(status=status.HTTP_204_NO_CONTENT)