From 31b06f1721f98730556dc56927b985e4032788c3 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 2 Oct 2012 19:54:20 +0100 Subject: [PATCH 1/4] Cleaner travis image link --- docs/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index e7db5dbc7..6e4d6257a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,5 @@ -[![Build Status](https://secure.travis-ci.org/tomchristie/django-rest-framework.png?branch=restframework2)][travis] +[![travis-build-image]][travis] # Django REST framework @@ -140,6 +140,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [travis]: http://travis-ci.org/tomchristie/django-rest-framework?branch=restframework2 +[travis-build-image]: https://secure.travis-ci.org/tomchristie/django-rest-framework.png?branch=restframework2 [urlobject]: https://github.com/zacharyvoase/urlobject [markdown]: http://pypi.python.org/pypi/Markdown/ [yaml]: http://pypi.python.org/pypi/PyYAML From eaecffe211eff12310d37ac6104af7c64ad37d34 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 2 Oct 2012 19:58:51 +0100 Subject: [PATCH 2/4] Remove duff checkin --- Django | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Django diff --git a/Django b/Django deleted file mode 100644 index e69de29bb..000000000 From b89125ef53a2f9e246afd5eda5c8f404a714da76 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 2 Oct 2012 21:26:15 +0100 Subject: [PATCH 3/4] Update view docs slightly --- docs/api-guide/generic-views.md | 43 +++++++++++++++++++++++++++------ rest_framework/mixins.py | 1 + 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 88f245c7a..b2284ae50 100644 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -9,9 +9,38 @@ One of the key benefits of class based views is the way they allow you to compose bits of reusable behaviour. REST framework takes advantage of this by providing a number of pre-built views that provide for commonly used patterns. -## Example +The generic views provided by REST framework allow you to quickly build API views that map closely to your database models. -... +If the generic views don't suit the needs of your API, you can drop down to using the regular `APIView` class, or reuse the mixins and base classes used by the generic views to compose your own set of reusable generic views. + +## Examples + +Typically when using the generic views, you'll override the view, and set several class attributes. + + class UserList(generics.ListCreateAPIView): + serializer = UserSerializer + model = User + permissions = (IsAdminUser,) + paginate_by = 100 + +For more complex cases you might also want to override various methods on the view class. For example. + + class UserList(generics.ListCreateAPIView): + serializer = UserSerializer + model = User + permissions = (IsAdminUser,) + + def get_paginate_by(self): + """ + Use smaller pagination for HTML representations. + """ + if self.request.accepted_media_type == 'text/html': + return 10 + return 100 + +For very simple cases you might want to pass through any class attributes using the `.as_view()` method. For example, your URLconf might include something the following entry. + + url(r'^/users/', ListCreateAPIView.as_view(model=User) name='user-list') --- @@ -19,7 +48,7 @@ One of the key benefits of class based views is the way they allow you to compos ## ListAPIView -Used for read-write endpoints to represent a collection of model instances. +Used for read-only endpoints to represent a collection of model instances. Provides a `get` method handler. @@ -45,6 +74,8 @@ Provides `get`, `put` and `delete` method handlers. # Base views +Each of the generic views provided is built by combining one of the base views below, with one or more mixin classes. + ## BaseAPIView Extends REST framework's `APIView` class, adding support for serialization of model instances and model querysets. @@ -65,7 +96,7 @@ Provides a base view for acting on a single object, by combining REST framework' # Mixins -The mixin classes provide the actions that are used +The mixin classes provide the actions that are used to provide the basic view behaviour. Note that the mixin classes provide action methods rather than defining the handler methods such as `.get()` and `.post()` directly. This allows for more flexible composition of behaviour. ## ListModelMixin @@ -87,10 +118,6 @@ Provides a `.update(request, *args, **kwargs)` method, that implements updating Provides a `.destroy(request, *args, **kwargs)` method, that implements deletion of an existing model instance. -## MetadataMixin - -Provides a `.metadata(request, *args, **kwargs)` method, that returns a response containing metadata about the view. - [cite]: https://docs.djangoproject.com/en/dev/ref/class-based-views/#base-vs-generic-views [MultipleObjectMixin]: https://docs.djangoproject.com/en/dev/ref/class-based-views/mixins-multiple-object/ [SingleObjectMixin]: https://docs.djangoproject.com/en/dev/ref/class-based-views/mixins-single-object/ diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index 167cd89aa..d391755c7 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -92,6 +92,7 @@ class DestroyModelMixin(object): return Response(status=status.HTTP_204_NO_CONTENT) +# TODO: Remove MetadataMixin, and implement on APIView.options() class MetadataMixin(object): """ Return a dicitonary of view metadata. From 934492ebd02dfc580fd0dbd9d8a57ca123adb46d Mon Sep 17 00:00:00 2001 From: Matt Bosworth Date: Tue, 2 Oct 2012 22:41:03 -0700 Subject: [PATCH 4/4] Fixed references to serializer.serialized and serializer.serialized_errors in part 3 of the tutorial. Altered part 1 to use blogs/urls.py since it was specified at the beginning. Also caught some spelling errors while I was at it. --- docs/tutorial/1-serialization.md | 6 +++--- docs/tutorial/2-requests-and-responses.md | 4 ++-- docs/tutorial/3-class-based-views.md | 8 ++++---- docs/tutorial/6-resource-orientated-projects.md | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index cd4b75584..5d8303150 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -78,7 +78,7 @@ Don't forget to sync the database for the first time. ## Creating a Serializer class -We're going to create a simple Web API that we can use to edit these comment objects with. The first thing we need is a way of serializing and deserializing the objects into representations such as `json`. We do this by declaring serializers, that work very similarly to Django's forms. Create a file in the project named `serializers.py` and add the following. +We're going to create a simple Web API that we can use to edit these comment objects with. The first thing we need is a way of serializing and deserializing the objects into representations such as `json`. We do this by declaring serializers that work very similarly to Django's forms. Create a file in the project named `serializers.py` and add the following. from blog import models from rest_framework import serializers @@ -201,7 +201,7 @@ The root of our API is going to be a view that supports listing all the existing Note that because we want to be able to POST to this view from clients that won't have a CSRF token we need to mark the view as `csrf_exempt`. This isn't something that you'd normally want to do, and REST framework views actually use more sensible behavior than this, but it'll do for our purposes right now. -We'll also need a view which corrosponds to an individual comment, and can be used to retrieve, update or delete the comment. +We'll also need a view which corresponds to an individual comment, and can be used to retrieve, update or delete the comment. @csrf_exempt def comment_instance(request, pk): @@ -231,7 +231,7 @@ We'll also need a view which corrosponds to an individual comment, and can be us comment.delete() return HttpResponse(status=204) -Finally we need to wire these views up, in the `tutorial/urls.py` file. +Finally we need to wire these views up. Create the `blog/urls.py` file: from django.conf.urls import patterns, url diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index d889b1e00..13feb2546 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -27,7 +27,7 @@ REST framework provides two wrappers you can use to write API views. 1. The `@api_view` decorator for working with function based views. 2. The `APIView` class for working with class based views. -These wrappers provide a few bits of functionality such as making sure you recieve `Request` instances in your view, and adding context to `Response` objects so that content negotiation can be performed. +These wrappers provide a few bits of functionality such as making sure you receive `Request` instances in your view, and adding context to `Response` objects so that content negotiation can be performed. The wrappers also provide behaviour such as returning `405 Method Not Allowed` responses when appropriate, and handling any `ParseError` exception that occurs when accessing `request.DATA` with malformed input. @@ -121,7 +121,7 @@ Now update the `urls.py` file slightly, to append a set of `format_suffix_patter urlpatterns = format_suffix_patterns(urlpatterns) -We don't necessarily need to add these extra url patterns in, but it gives us a simple, clean way of refering to a specific format. +We don't necessarily need to add these extra url patterns in, but it gives us a simple, clean way of referring to a specific format. ## How's it looking? diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index 25d5773f1..b2b6443c5 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -28,10 +28,10 @@ We'll start by rewriting the root view as a class based view. All this involves if serializer.is_valid(): comment = serializer.object comment.save() - return Response(serializer.serialized, status=status.HTTP_201_CREATED) - return Response(serializer.serialized_errors, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) -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. +So far, so good. It looks pretty similar to the previous case, but we've got better separation between the different HTTP methods. We'll also need to update the instance view. class CommentInstance(APIView): """ @@ -145,7 +145,7 @@ Using the mixin classes we've rewritten the views to use slightly less code than model = Comment serializer_class = CommentSerializer -Wow, that's pretty concise. We've got a huge amount for free, and our code looks like good, clean, idomatic Django. +Wow, that's pretty concise. We've got a huge amount for free, and our code looks like good, clean, idiomatic Django. Next we'll move onto [part 4 of the tutorial][tut-4], 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. diff --git a/docs/tutorial/6-resource-orientated-projects.md b/docs/tutorial/6-resource-orientated-projects.md index 3c3e7fedc..e7190a772 100644 --- a/docs/tutorial/6-resource-orientated-projects.md +++ b/docs/tutorial/6-resource-orientated-projects.md @@ -4,8 +4,8 @@ Resource classes are just View classes that don't have any handler methods bound This allows us to: -* Encapsulate common behaviour accross a class of views, in a single Resource class. -* Seperate out the actions of a Resource from the specfics of how those actions should be bound to a particular set of URLs. +* Encapsulate common behaviour across a class of views, in a single Resource class. +* Separate out the actions of a Resource from the specfics of how those actions should be bound to a particular set of URLs. ## Refactoring to use Resources, not Views @@ -59,7 +59,7 @@ Right now that hasn't really saved us a lot of code. However, now that we're us ## Trade-offs between views vs resources. -Writing resource-orientated code can be a good thing. It helps ensure that URL conventions will be consistent across your APIs, and minimises the amount of code you need to write. +Writing resource-oriented code can be a good thing. It helps ensure that URL conventions will be consistent across your APIs, and minimises the amount of code you need to write. The trade-off is that the behaviour is less explict. It can be more difficult to determine what code path is being followed, or where to override some behaviour.