Tweak tutorial slightly

This commit is contained in:
Tom Christie 2012-09-07 09:45:23 +01:00
parent 07fe60772c
commit 57e9a36c3a
2 changed files with 28 additions and 18 deletions

View File

@ -126,7 +126,7 @@ margin-top: 5px;
<div class="span3">
<div class="well affix span3">
<ul class="nav nav-list side-nav">
<li class="main"><a href="#tutorial-2-request-and-response-objects">Tutorial 2: Request and Response objects</a></li>
<li class="main"><a href="#tutorial-2-requests-and-responses">Tutorial 2: Requests and Responses</a></li>
<li><a href="#request-objects">Request objects</a></li>
<li><a href="#response-objects">Response objects</a></li>
<li><a href="#status-codes">Status codes</a></li>
@ -141,7 +141,7 @@ margin-top: 5px;
</div>
<div class="span9">
<h1 id="tutorial-2-request-and-response-objects">Tutorial 2: Request and Response objects</h1>
<h1 id="tutorial-2-requests-and-responses">Tutorial 2: Requests and Responses</h1>
<p>From this point we're going to really start covering the core of REST framework.
Let's introduce a couple of essential building blocks.</p>
<h2 id="request-objects">Request objects</h2>

View File

@ -126,17 +126,17 @@ margin-top: 5px;
<div class="span3">
<div class="well affix span3">
<ul class="nav nav-list side-nav">
<li class="main"><a href="#tutorial-3-using-class-based-views">Tutorial 3: Using Class Based Views</a></li>
<li class="main"><a href="#tutorial-3-class-based-views">Tutorial 3: Class Based Views</a></li>
<li><a href="#rewriting-our-api-using-class-based-views">Rewriting our API using class based views</a></li>
<li><a href="#using-mixins">Using mixins</a></li>
<li><a href="#reusing-generic-class-based-views">Reusing generic class based views</a></li>
<li><a href="#using-generic-class-based-views">Using generic class based views</a></li>
</ul>
</div>
</div>
<div class="span9">
<h1 id="tutorial-3-using-class-based-views">Tutorial 3: Using Class Based Views</h1>
<h1 id="tutorial-3-class-based-views">Tutorial 3: Class Based Views</h1>
<p>We can also write our API views using class based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</p>
<h2 id="rewriting-our-api-using-class-based-views">Rewriting our API using class based views</h2>
<p>We'll start by rewriting the root view as a class based view. All this involves is a little bit of refactoring.</p>
@ -203,16 +203,16 @@ class CommentRoot(APIView):
Okay, we're done. If you run the development server everything should be working just as before.</p>
<h2 id="using-mixins">Using mixins</h2>
<p>One of the big wins of using class based views is that it allows us to easily compose reusable bits of behaviour.</p>
<p>The create/retrieve/update/delete operations that we've been using so far is going to be pretty simliar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes.</p>
<p>We can compose those mixin classes, to recreate our existing API behaviour with less code.</p>
<p>The create/retrieve/update/delete operations that we've been using so far are going to be pretty simliar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes.</p>
<p>Let's take a look at how we can compose our views by using the mixin classes.</p>
<pre><code>from blog.models import Comment
from blog.serializers import CommentSerializer
from djangorestframework import mixins
from djangorestframework import views
from djangorestframework import generics
class CommentRoot(mixins.ListModelMixin,
mixins.CreateModelMixin,
views.MultipleObjectBaseView):
generics.MultipleObjectBaseView):
model = Comment
serializer_class = CommentSerializer
@ -222,10 +222,14 @@ class CommentRoot(mixins.ListModelMixin,
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class CommentInstance(mixins.RetrieveModelMixin,
comment_root = CommentRoot.as_view()
</code></pre>
<p>We'll take a moment to examine exactly what's happening here - We're building our view using <code>MultipleObjectBaseView</code>, and adding in <code>ListModelMixin</code> and <code>CreateModelMixin</code>.</p>
<p>The base class provides the core functionality, and the mixin classes provide the <code>.list()</code> and <code>.create()</code> actions. We're then explictly binding the <code>get</code> and <code>post</code> methods to the appropriate actions. Simple enough stuff so far.</p>
<pre><code>class CommentInstance(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
views.SingleObjectBaseView):
generics.SingleObjectBaseView):
model = Comment
serializer_class = CommentSerializer
@ -237,23 +241,29 @@ class CommentInstance(mixins.RetrieveModelMixin,
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
comment_instance = CommentInstance.as_view()
</code></pre>
<h2 id="reusing-generic-class-based-views">Reusing generic class based views</h2>
<p>That's a lot less code than before, but we can go one step further still. REST framework also provides a set of already mixed-in views.</p>
<p>Pretty similar. This time we're using the <code>SingleObjectBaseView</code> class to provide the core functionality, and adding in mixins to provide the <code>.retrieve()</code>, <code>.update()</code> and <code>.destroy()</code> actions.</p>
<h2 id="using-generic-class-based-views">Using generic class based views</h2>
<p>Using the mixin classes we've rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use.</p>
<pre><code>from blog.models import Comment
from blog.serializers import CommentSerializer
from djangorestframework import views
from djangorestframework import generics
class CommentRoot(views.RootModelView):
class CommentRoot(generics.RootAPIView):
model = Comment
serializer_class = CommentSerializer
class CommentInstance(views.InstanceModelView):
comment_root = CommentRoot.as_view()
class CommentInstance(generics.InstanceAPIView):
model = Comment
serializer_class = CommentSerializer
comment_instance = CommentInstance.as_view()
</code></pre>
<p>Wow, that's pretty concise. We've got a huge amount for free, and our code looks like
good, clean, idomatic Django.</p>
<p>Wow, that's pretty concise. We've got a huge amount for free, and our code looks like good, clean, idomatic Django.</p>
<p>Next we'll move onto <a href="4-authentication-permissions-and-throttling">part 4 of the tutorial</a>, 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.</p>
</div><!--/span-->
</div><!--/row-->