> You keep using that word "REST". I do not think it means what you think it means.
>
> — Mike Amundsen, [talking at REST fest 2012][cite].
# REST, Hypermedia & HATEOAS
> — Mike Amundsen, [REST fest 2012 keynote][cite].
First off, the disclaimer. The name "Django REST framework" was choosen with a view to making sure the project would be easily found by developers. Throughout the documentation we try to use the more simple and technically correct terminology of "Web APIs".
Our instance view is an improvement over the previous example. It's a little more concise, and the code now feels very similar to if we were working with the Forms API. We're also using named status codes, which makes the response meanings more obvious.
...
...
@@ -87,7 +87,7 @@ Our instance view is an improvement over the previous example. It's a little mo
So far, so good. It looks pretty similar to the previous case, but we've got better seperation between the different HTTP methods. We'll also need to update the instance view.
class CommentInstance(APIView):
...
...
@@ -58,16 +56,28 @@ So far, so good. It looks pretty similar to the previous case, but we've got be
Okay, we're done. If you run the development server everything should be working just as before.
## Using mixins
...
...
@@ -95,8 +105,6 @@ Let's take a look at how we can compose our views by using the mixin classes.
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
comment_root = CommentRoot.as_view()
We'll take a moment to examine exactly what's happening here - We're building our view using `MultipleObjectBaseView`, and adding in `ListModelMixin` and `CreateModelMixin`.
The base class provides the core functionality, and the mixin classes provide the `.list()` and `.create()` actions. We're then explictly binding the `get` and `post` methods to the appropriate actions. Simple enough stuff so far.
...
...
@@ -117,8 +125,6 @@ The base class provides the core functionality, and the mixin classes provide th
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
comment_instance = CommentInstance.as_view()
Pretty similar. This time we're using the `SingleObjectBaseView` class to provide the core functionality, and adding in mixins to provide the `.retrieve()`, `.update()` and `.destroy()` actions.
## Using generic class based views
...
...
@@ -134,16 +140,11 @@ Using the mixin classes we've rewritten the views to use slightly less code than
model = Comment
serializer_class = CommentSerializer
comment_root = CommentRoot.as_view()
class CommentInstance(generics.InstanceAPIView):
model = Comment
serializer_class = CommentSerializer
comment_instance = CommentInstance.as_view()
Wow, that's pretty concise. We've got a huge amount for free, and our code looks like good, clean, idomatic Django.
Next we'll move onto [part 4 of the tutorial][2], where we'll take a look at how we can customize the behavior of our views to support a range of authentication, permissions, throttling and other aspects.