diff options
| author | Tom Christie | 2013-04-24 22:40:24 +0100 | 
|---|---|---|
| committer | Tom Christie | 2013-04-24 22:40:24 +0100 | 
| commit | b94da2468cdda6b0ad491574d35097d0e336ea7f (patch) | |
| tree | bfb05f85703a738918252c8968f9a460554cae3f /docs/tutorial | |
| parent | 835d3f89d37b873b2ef96dc7d71922b035b07328 (diff) | |
| download | django-rest-framework-b94da2468cdda6b0ad491574d35097d0e336ea7f.tar.bz2 | |
Various clean up and lots of docs
Diffstat (limited to 'docs/tutorial')
| -rw-r--r-- | docs/tutorial/3-class-based-views.md | 16 | ||||
| -rw-r--r-- | docs/tutorial/4-authentication-and-permissions.md | 4 | ||||
| -rw-r--r-- | docs/tutorial/5-relationships-and-hyperlinked-apis.md | 30 | ||||
| -rw-r--r-- | docs/tutorial/6-viewsets-and-routers.md | 52 | 
4 files changed, 56 insertions, 46 deletions
| diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index e05017c5..70cf2c54 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -92,8 +92,8 @@ Let's take a look at how we can compose our views by using the mixin classes.      class SnippetList(mixins.ListModelMixin,                        mixins.CreateModelMixin, -                      generics.MultipleObjectAPIView): -        model = Snippet +                      generics.GenericAPIView): +        queryset = Snippet.objects.all()          serializer_class = SnippetSerializer          def get(self, request, *args, **kwargs): @@ -102,15 +102,15 @@ 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) -We'll take a moment to examine exactly what's happening here. We're building our view using `MultipleObjectAPIView`, and adding in `ListModelMixin` and `CreateModelMixin`. +We'll take a moment to examine exactly what's happening here. We're building our view using `GenericAPIView`, 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 explicitly binding the `get` and `post` methods to the appropriate actions.  Simple enough stuff so far.      class SnippetDetail(mixins.RetrieveModelMixin,                          mixins.UpdateModelMixin,                          mixins.DestroyModelMixin, -                        generics.SingleObjectAPIView): -        model = Snippet +                        generics.GenericAPIView): +        queryset = Snippet.objects.all()          serializer_class = SnippetSerializer          def get(self, request, *args, **kwargs): @@ -122,7 +122,7 @@ 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) -Pretty similar.  This time we're using the `SingleObjectAPIView` class to provide the core functionality, and adding in mixins to provide the `.retrieve()`, `.update()` and `.destroy()` actions. +Pretty similar.  Again we're using the `GenericAPIView` class to provide the core functionality, and adding in mixins to provide the `.retrieve()`, `.update()` and `.destroy()` actions.  ## Using generic class based views @@ -134,12 +134,12 @@ Using the mixin classes we've rewritten the views to use slightly less code than      class SnippetList(generics.ListCreateAPIView): -        model = Snippet +        queryset = Snippet.objects.all()          serializer_class = SnippetSerializer      class SnippetDetail(generics.RetrieveUpdateDestroyAPIView): -        model = Snippet +        queryset = Snippet.objects.all()          serializer_class = SnippetSerializer  Wow, that's pretty concise.  We've gotten a huge amount for free, and our code looks like good, clean, idiomatic Django. diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 878672bb..d3ee8e79 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -68,12 +68,12 @@ Because `'snippets'` is a *reverse* relationship on the User model, it will not  We'll also add a couple of views.  We'd like to just use read-only views for the user representations, so we'll use the `ListAPIView` and `RetrieveAPIView` generic class based views.      class UserList(generics.ListAPIView): -        model = User +        queryset = User.objects.all()          serializer_class = UserSerializer      class UserDetail(generics.RetrieveAPIView): -        model = User +        queryset = User.objects.all()          serializer_class = UserSerializer  Finally we need to add those views into the API, by referencing them from the URL conf. diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index 27a10840..c9c37547 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -34,8 +34,8 @@ Instead of using a concrete generic view, we'll use the base class for represent      from rest_framework import renderers      from rest_framework.response import Response -    class SnippetHighlight(generics.SingleObjectAPIView): -        model = Snippet +    class SnippetHighlight(generics.GenericAPIView): +        queryset = Snippet.objects.all()          renderer_classes = (renderers.StaticHTMLRenderer,)          def get(self, request, *args, **kwargs): @@ -143,34 +143,16 @@ We can change the default list style to use pagination, by modifying our `settin          'PAGINATE_BY': 10      } -Note that settings in REST framework are all namespaced into a single dictionary setting, named 'REST_FRAMEWORK', which helps keep them well seperated from your other project settings. +Note that settings in REST framework are all namespaced into a single dictionary setting, named 'REST_FRAMEWORK', which helps keep them well separated from your other project settings.  We could also customize the pagination style if we needed too, but in this case we'll just stick with the default. -## Reviewing our work +## Browsing the API  If we open a browser and navigate to the browseable API, you'll find that you can now work your way around the API simply by following links.  You'll also be able to see the 'highlight' links on the snippet instances, that will take you to the highlighted code HTML representations. -We've now got a complete pastebin Web API, which is fully web browseable, and comes complete with authentication, per-object permissions, and multiple renderer formats. +In [part 6][tut-6] of the tutorial we'll look at how we can use ViewSets and Routers to reduce the amount of code we need to build our API. -We've walked through each step of the design process, and seen how if we need to customize anything we can gradually work our way down to simply using regular Django views. - -You can review the final [tutorial code][repo] on GitHub, or try out a live example in [the sandbox][sandbox].  - -## Onwards and upwards - -We've reached the end of our tutorial.  If you want to get more involved in the REST framework project, here's a few places you can start: - -* Contribute on [GitHub][github] by reviewing and submitting issues, and making pull requests. -* Join the [REST framework discussion group][group], and help build the community. -* Follow [the author][twitter] on Twitter and say hi. - -**Now go build awesome things.** - -[repo]: https://github.com/tomchristie/rest-framework-tutorial -[sandbox]: http://restframework.herokuapp.com/ -[github]: https://github.com/tomchristie/django-rest-framework -[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework -[twitter]: https://twitter.com/_tomchristie +[tut-6]: 6-viewsets-and-routers.md diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index 4c1a1abd..876d89ac 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -1,6 +1,6 @@  # Tutorial 6 - ViewSets & Routers -REST framework includes an abstraction for dealing with `ViewSets`, that allows the developer to concentrate on modelling the state and interactions of the API, and leave the URL construction to be handled automatically, based on common conventions. +REST framework includes an abstraction for dealing with `ViewSets`, that allows the developer to concentrate on modeling the state and interactions of the API, and leave the URL construction to be handled automatically, based on common conventions.  `ViewSet` classes are almost the same thing as `View` classes, except that they provide operations such as `read`, or `update`, and not method handlers such as `get` or `put`. @@ -19,7 +19,7 @@ First of all let's refactor our `UserListView` and `UserDetailView` views into a          queryset = User.objects.all()          serializer_class = UserSerializer -Here we've used `ReadOnlyModelViewSet` class to automatically provide the default 'read-only' operations.  We're still setting the `queryset` and `serializer_class` attributes exactly as we did when we were using regular views, but we no longer need to provide the same information to two seperate classes. +Here we've used `ReadOnlyModelViewSet` class to automatically provide the default 'read-only' operations.  We're still setting the `queryset` and `serializer_class` attributes exactly as we did when we were using regular views, but we no longer need to provide the same information to two separate classes.  Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighlight` view classes.  We can remove the three views, and again replace them with a single class. @@ -103,21 +103,49 @@ Here's our re-wired `urls.py` file.      from snippets import views      from rest_framework.routers import DefaultRouter -    # Create a router and register our views and view sets with it. +    # Create a router and register our viewsets with it.      router = DefaultRouter() -    router.register(r'^/$', views.api_root) -    router.register(r'^snippets/', views.SnippetViewSet, 'snippet') -    router.register(r'^users/', views.UserViewSet, 'user') +    router.register(r'snippets', views.SnippetViewSet, 'snippet') +    router.register(r'users', views.UserViewSet, 'user') -    # The urlconf is determined automatically by the router. -    urlpatterns = router.urlpatterns -     -    # We can still add format suffixes to all our URL patterns. -    urlpatterns = format_suffix_patterns(urlpatterns) +    # The API URLs are now determined automatically by the router. +    # Additionally, we include the login URLs for the browseable API. +    urlpatterns = patterns('', +        url(r'^', include(router.urls)), +        url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) +    ) + +Registering the viewsets with the router is similar to providing a urlpattern.  We include three arguments - the URL prefix for the views, the viewset itself, and the base name that should be used for constructing the URL names, such as `snippet-list`. + +The `DefaultRouter` class we're using also automatically creates the API root view for us, so we can now delete the `api_root` method from our `views` module.  ## Trade-offs between views vs viewsets. -Using view sets can be a really useful abstraction.  It helps ensure that URL conventions will be consistent across your API, minimises the amount of code you need to write, and allows you to concentrate on the interactions and representations your API provides rather than the specifics of the URL conf. +Using viewsets can be a really useful abstraction.  It helps ensure that URL conventions will be consistent across your API, minimizes the amount of code you need to write, and allows you to concentrate on the interactions and representations your API provides rather than the specifics of the URL conf.  That doesn't mean it's always the right approach to take.  There's a similar set of trade-offs to consider as when using class-based views instead of function based views.  Using view sets is less explicit than building your views individually. +## Reviewing our work + +With an incredibly small amount of code, we've now got a complete pastebin Web API, which is fully web browseable, and comes complete with authentication, per-object permissions, and multiple renderer formats. + +We've walked through each step of the design process, and seen how if we need to customize anything we can gradually work our way down to simply using regular Django views. + +You can review the final [tutorial code][repo] on GitHub, or try out a live example in [the sandbox][sandbox].  + +## Onwards and upwards + +We've reached the end of our tutorial.  If you want to get more involved in the REST framework project, here's a few places you can start: + +* Contribute on [GitHub][github] by reviewing and submitting issues, and making pull requests. +* Join the [REST framework discussion group][group], and help build the community. +* Follow [the author][twitter] on Twitter and say hi. + +**Now go build awesome things.** + + +[repo]: https://github.com/tomchristie/rest-framework-tutorial +[sandbox]: http://restframework.herokuapp.com/ +[github]: https://github.com/tomchristie/django-rest-framework +[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework +[twitter]: https://twitter.com/_tomchristie
\ No newline at end of file | 
