From eaae8fb2d973769a827214e0606a7e41028d5d34 Mon Sep 17 00:00:00 2001 From: Alex Burgel Date: Mon, 15 Jul 2013 18:35:13 -0400 Subject: Combined link_* and action_* decorators into detail_route and list_route, marked the originals as deprecated. --- docs/tutorial/6-viewsets-and-routers.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index f16add39..f126ba04 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -25,7 +25,7 @@ Here we've used `ReadOnlyModelViewSet` class to automatically provide the defaul 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. - from rest_framework.decorators import link + from rest_framework.decorators import detail_route class SnippetViewSet(viewsets.ModelViewSet): """ @@ -39,7 +39,7 @@ Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighl permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) - @link(renderer_classes=[renderers.StaticHTMLRenderer]) + @detail_route(renderer_classes=[renderers.StaticHTMLRenderer]) def highlight(self, request, *args, **kwargs): snippet = self.get_object() return Response(snippet.highlighted) @@ -49,9 +49,9 @@ Next we're going to replace the `SnippetList`, `SnippetDetail` and `SnippetHighl This time we've used the `ModelViewSet` class in order to get the complete set of default read and write operations. -Notice that we've also used the `@link` decorator to create a custom action, named `highlight`. This decorator can be used to add any custom endpoints that don't fit into the standard `create`/`update`/`delete` style. +Notice that we've also used the `@detail_route` decorator to create a custom action, named `highlight`. This decorator can be used to add any custom endpoints that don't fit into the standard `create`/`update`/`delete` style. -Custom actions which use the `@link` decorator will respond to `GET` requests. We could have instead used the `@action` decorator if we wanted an action that responded to `POST` requests. +Custom actions which use the `@detail_route` decorator will respond to `GET` requests. We can use the `methods` argument if we wanted an action that responded to `POST` requests. ## Binding ViewSets to URLs explicitly -- cgit v1.2.3 From cdc7d19034170e5d775166763e6df1220e131d35 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Mon, 5 May 2014 14:41:10 +0200 Subject: Added missing "to" word --- docs/tutorial/1-serialization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 979c4a3e..dbe693ed 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -104,7 +104,7 @@ Don't forget to sync the database for the first time. ## Creating a Serializer class -The first thing we need to get started on our Web API is provide a way of serializing and deserializing the snippet instances into representations such as `json`. We can do this by declaring serializers that work very similar to Django's forms. Create a file in the `snippets` directory named `serializers.py` and add the following. +The first thing we need to get started on our Web API is to provide a way of serializing and deserializing the snippet instances into representations such as `json`. We can do this by declaring serializers that work very similar to Django's forms. Create a file in the `snippets` directory named `serializers.py` and add the following. from django.forms import widgets from rest_framework import serializers -- cgit v1.2.3 From 05fc974dc961de6d4e11b7baf51f7b3791c06711 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Mon, 5 May 2014 14:44:54 +0200 Subject: Added missing "the" word --- docs/tutorial/1-serialization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index dbe693ed..55b19457 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -143,7 +143,7 @@ The first thing we need to get started on our Web API is to provide a way of ser # Create new instance return Snippet(**attrs) -The first part of serializer class defines the fields that get serialized/deserialized. The `restore_object` method defines how fully fledged instances get created when deserializing data. +The first part of the serializer class defines the fields that get serialized/deserialized. The `restore_object` method defines how fully fledged instances get created when deserializing data. Notice that we can also use various attributes that would typically be used on form fields, such as `widget=widgets.Textarea`. These can be used to control how the serializer should render when displayed as an HTML form. This is particularly useful for controlling how the browsable API should be displayed, as we'll see later in the tutorial. -- cgit v1.2.3 From 9e3ba939e152c2eb96d3c9b4460a3d4ce76931cd Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Mon, 5 May 2014 20:27:44 +0200 Subject: Removed superfluous "./"s --- docs/tutorial/4-authentication-and-permissions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 432371f3..491df160 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -44,11 +44,11 @@ When that's all done we'll need to update our database tables. Normally we'd create a database migration in order to do that, but for the purposes of this tutorial, let's just delete the database and start again. rm tmp.db - python ./manage.py syncdb + python manage.py syncdb You might also want to create a few different users, to use for testing the API. The quickest way to do this will be with the `createsuperuser` command. - python ./manage.py createsuperuser + python manage.py createsuperuser ## Adding endpoints for our User models -- cgit v1.2.3 From 9dc5e15e5afaf806378bb52ea2134f8dec2af386 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Tue, 6 May 2014 13:00:41 +0200 Subject: Added missing "the" word --- docs/tutorial/6-viewsets-and-routers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index 870632f1..0a7c3363 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -21,7 +21,7 @@ First of all let's refactor our `UserList` and `UserDetail` views into a single 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 separate classes. +Here we've used the `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. -- cgit v1.2.3 From beb7253a961870a37833b7df6d1dfd3e8c1db778 Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Tue, 6 May 2014 15:06:38 +0200 Subject: Removed unnecessary "that" --- docs/tutorial/6-viewsets-and-routers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index 0a7c3363..dad71601 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -85,7 +85,7 @@ In the `urls.py` file we bind our `ViewSet` classes into a set of concrete views Notice how we're creating multiple views from each `ViewSet` class, by binding the http methods to the required action for each view. -Now that we've bound our resources into concrete views, that we can register the views with the URL conf as usual. +Now that we've bound our resources into concrete views, we can register the views with the URL conf as usual. urlpatterns = format_suffix_patterns(patterns('snippets.views', url(r'^$', 'api_root'), -- cgit v1.2.3 From e033a0b9a0d655666385cd9831c7f1279573b47f Mon Sep 17 00:00:00 2001 From: Sylvain Bellemare Date: Tue, 6 May 2014 15:07:40 +0200 Subject: Replaced singular "is" by plural "are" --- docs/tutorial/6-viewsets-and-routers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/6-viewsets-and-routers.md b/docs/tutorial/6-viewsets-and-routers.md index dad71601..04b42f2e 100644 --- a/docs/tutorial/6-viewsets-and-routers.md +++ b/docs/tutorial/6-viewsets-and-routers.md @@ -138,7 +138,7 @@ You can review the final [tutorial code][repo] on GitHub, or try out a live exam ## 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: +We've reached the end of our tutorial. If you want to get more involved in the REST framework project, here are 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. -- cgit v1.2.3 From 18eab53e892f2f579fd0bb4e1ca3cb47a074accc Mon Sep 17 00:00:00 2001 From: Emmanouil Date: Wed, 9 Jul 2014 15:53:31 +0100 Subject: Updated quick start project set up order --- docs/tutorial/quickstart.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md index 8bf8c7f5..04792c69 100644 --- a/docs/tutorial/quickstart.md +++ b/docs/tutorial/quickstart.md @@ -6,8 +6,8 @@ We're going to create a simple API to allow admin users to view and edit the use Create a new Django project named `tutorial`, then start a new app called `quickstart`. - # Set up a new project - django-admin.py startproject tutorial + # Create the project directory + mkdir tutorial cd tutorial # Create a virtualenv to isolate our package dependencies locally @@ -18,6 +18,9 @@ Create a new Django project named `tutorial`, then start a new app called `quick pip install django pip install djangorestframework + # Set up a new project + django-admin.py startproject tutorial + # Create a new app python manage.py startapp quickstart -- cgit v1.2.3 From 62d0d4e5d2f203d2c1694af363bce88cc1a5d483 Mon Sep 17 00:00:00 2001 From: nimiq Date: Wed, 6 Aug 2014 12:45:58 +0200 Subject: Fix style for some text --- docs/tutorial/5-relationships-and-hyperlinked-apis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index 2cf44bf9..aef92d08 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -29,7 +29,7 @@ Unlike all our other API endpoints, we don't want to use JSON, but instead just The other thing we need to consider when creating the code highlight view is that there's no existing concrete generic view that we can use. We're not returning an object instance, but instead a property of an object instance. -Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your snippets.views add: +Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your `snippets.views` add: from rest_framework import renderers from rest_framework.response import Response -- cgit v1.2.3 From 14867705e90b2b5f7e84dc7385d4ffba0c82b3e1 Mon Sep 17 00:00:00 2001 From: sshquack Date: Fri, 15 Aug 2014 20:41:21 -0600 Subject: Specify file names using standard format + Explicitly specify module names in the standard format similar to all the other tutorials + Remove the extra quote around module name --- docs/tutorial/4-authentication-and-permissions.md | 2 +- docs/tutorial/5-relationships-and-hyperlinked-apis.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 491df160..bdbe00ab 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -129,7 +129,7 @@ Then, add the following property to **both** the `SnippetList` and `SnippetDetai If you open a browser and navigate to the browsable API at the moment, you'll find that you're no longer able to create new code snippets. In order to do so we'd need to be able to login as a user. -We can add a login view for use with the browsable API, by editing the URLconf in our project-level urls.py file. +We can add a login view for use with the browsable API, by editing the URLconf in our project-level `urls.py` file. Add the following import at the top of the file: diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index aef92d08..deddb13f 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -4,7 +4,7 @@ At the moment relationships within our API are represented by using primary keys ## Creating an endpoint for the root of our API -Right now we have endpoints for 'snippets' and 'users', but we don't have a single entry point to our API. To create one, we'll use a regular function-based view and the `@api_view` decorator we introduced earlier. +Right now we have endpoints for 'snippets' and 'users', but we don't have a single entry point to our API. To create one, we'll use a regular function-based view and the `@api_view` decorator we introduced earlier. In your `snippets/views.py` add: from rest_framework import renderers from rest_framework.decorators import api_view @@ -29,7 +29,7 @@ Unlike all our other API endpoints, we don't want to use JSON, but instead just The other thing we need to consider when creating the code highlight view is that there's no existing concrete generic view that we can use. We're not returning an object instance, but instead a property of an object instance. -Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your `snippets.views` add: +Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your `snippets/views.py` add: from rest_framework import renderers from rest_framework.response import Response @@ -43,7 +43,7 @@ Instead of using a concrete generic view, we'll use the base class for represent return Response(snippet.highlighted) As usual we need to add the new views that we've created in to our URLconf. -We'll add a url pattern for our new API root: +We'll add a url pattern for our new API root in `snippets/urls.py`: url(r'^$', 'api_root'), @@ -73,7 +73,7 @@ The `HyperlinkedModelSerializer` has the following differences from `ModelSerial * Relationships use `HyperlinkedRelatedField`, instead of `PrimaryKeyRelatedField`. -We can easily re-write our existing serializers to use hyperlinking. +We can easily re-write our existing serializers to use hyperlinking. In your `snippets/serializers.py` add: class SnippetSerializer(serializers.HyperlinkedModelSerializer): owner = serializers.Field(source='owner.username') @@ -105,7 +105,7 @@ If we're going to have a hyperlinked API, we need to make sure we name our URL p * Our user serializer includes a field that refers to `'snippet-detail'`. * Our snippet and user serializers include `'url'` fields that by default will refer to `'{model_name}-detail'`, which in this case will be `'snippet-detail'` and `'user-detail'`. -After adding all those names into our URLconf, our final `'urls.py'` file should look something like this: +After adding all those names into our URLconf, our final `snippets/urls.py` file should look something like this: # API endpoints urlpatterns = format_suffix_patterns(patterns('snippets.views', -- cgit v1.2.3 From 867e441ec07fc182569c3dbe6f86fe42aa6b0cbf Mon Sep 17 00:00:00 2001 From: sshquack Date: Fri, 15 Aug 2014 20:45:28 -0600 Subject: Strip trailing spaces in tutorial --- docs/tutorial/1-serialization.md | 20 ++++++------ docs/tutorial/2-requests-and-responses.md | 8 ++--- docs/tutorial/3-class-based-views.md | 4 +-- docs/tutorial/4-authentication-and-permissions.md | 12 +++---- .../5-relationships-and-hyperlinked-apis.md | 16 ++++----- docs/tutorial/quickstart.md | 38 +++++++++++----------- 6 files changed, 49 insertions(+), 49 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 55b19457..96214f5b 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -81,8 +81,8 @@ For the purposes of this tutorial we're going to start by creating a simple `Sni LEXERS = [item for item in get_all_lexers() if item[1]] LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS]) STYLE_CHOICES = sorted((item, item) for item in get_all_styles()) - - + + class Snippet(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=True, default='') @@ -94,7 +94,7 @@ For the purposes of this tutorial we're going to start by creating a simple `Sni style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100) - + class Meta: ordering = ('created',) @@ -122,12 +122,12 @@ The first thing we need to get started on our Web API is to provide a way of ser default='python') style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly') - + def restore_object(self, attrs, instance=None): """ Create or update a new snippet instance, given a dictionary of deserialized field values. - + Note that if we don't define this method, then deserializing data will simply return a dictionary of items. """ @@ -180,7 +180,7 @@ At this point we've translated the model instance into Python native datatypes. content # '{"pk": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}' -Deserialization is similar. First we parse a stream into Python native datatypes... +Deserialization is similar. First we parse a stream into Python native datatypes... # This import will use either `StringIO.StringIO` or `io.BytesIO` # as appropriate, depending on if we're running Python 2 or Python 3. @@ -196,7 +196,7 @@ Deserialization is similar. First we parse a stream into Python native datatype # True serializer.object # - + Notice how similar the API is to working with forms. The similarity should become even more apparent when we start writing views that use our serializer. We can also serialize querysets instead of model instances. To do so we simply add a `many=True` flag to the serializer arguments. @@ -264,7 +264,7 @@ The root of our API is going to be a view that supports listing all the existing return JSONResponse(serializer.data, status=201) return JSONResponse(serializer.errors, status=400) -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. +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 corresponds to an individual snippet, and can be used to retrieve, update or delete the snippet. @@ -277,11 +277,11 @@ We'll also need a view which corresponds to an individual snippet, and can be us snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: return HttpResponse(status=404) - + if request.method == 'GET': serializer = SnippetSerializer(snippet) return JSONResponse(serializer.data) - + elif request.method == 'PUT': data = JSONParser().parse(request) serializer = SnippetSerializer(snippet, data=data) diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index 603edd08..e70bbbfc 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -33,7 +33,7 @@ The wrappers also provide behaviour such as returning `405 Method Not Allowed` r ## Pulling it all together -Okay, let's go ahead and start using these new components to write a few views. +Okay, let's go ahead and start using these new components to write a few views. We don't need our `JSONResponse` class in `views.py` anymore, so go ahead and delete that. Once that's done we can start refactoring our views slightly. @@ -69,7 +69,7 @@ Here is the view for an individual snippet, in the `views.py` module. def snippet_detail(request, pk): """ Retrieve, update or delete a snippet instance. - """ + """ try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: @@ -115,7 +115,7 @@ Now update the `urls.py` file slightly, to append a set of `format_suffix_patter url(r'^snippets/$', 'snippet_list'), url(r'^snippets/(?P[0-9]+)$', 'snippet_detail'), ) - + 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 referring to a specific format. @@ -146,7 +146,7 @@ Similarly, we can control the format of the request that we send, using the `Con curl -X POST http://127.0.0.1:8000/snippets/ -d "code=print 123" {"id": 3, "title": "", "code": "print 123", "linenos": false, "language": "python", "style": "friendly"} - + # POST using JSON curl -X POST http://127.0.0.1:8000/snippets/ -d '{"code": "print 456"}' -H "Content-Type: application/json" diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index b37bc31b..e04072ca 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -30,7 +30,7 @@ We'll start by rewriting the root view as a class based view. All this involves 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 separation between the different HTTP methods. We'll also need to update the instance view in `views.py`. +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 in `views.py`. class SnippetDetail(APIView): """ @@ -72,7 +72,7 @@ We'll also need to refactor our `urls.py` slightly now we're using class based v url(r'^snippets/$', views.SnippetList.as_view()), url(r'^snippets/(?P[0-9]+)/$', views.SnippetDetail.as_view()), ) - + urlpatterns = format_suffix_patterns(urlpatterns) Okay, we're done. If you run the development server everything should be working just as before. diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index bdbe00ab..74ad9a55 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -73,12 +73,12 @@ We'll also add a couple of views to `views.py`. We'd like to just use read-only class UserList(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserSerializer - - + + class UserDetail(generics.RetrieveAPIView): queryset = User.objects.all() serializer_class = UserSerializer - + Make sure to also import the `UserSerializer` class from snippets.serializers import UserSerializer @@ -157,8 +157,8 @@ To do that we're going to need to create a custom permission. In the snippets app, create a new file, `permissions.py` from rest_framework import permissions - - + + class IsOwnerOrReadOnly(permissions.BasePermission): """ Custom permission to only allow owners of an object to edit it. @@ -201,7 +201,7 @@ If we try to create a snippet without authenticating, we'll get an error: We can make a successful request by including the username and password of one of the users we created earlier. curl -X POST http://127.0.0.1:8000/snippets/ -d "code=print 789" -u tom:password - + {"id": 5, "owner": "tom", "title": "foo", "code": "print 789", "linenos": false, "language": "python", "style": "friendly"} ## Summary diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index deddb13f..9c61fe3d 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -1,6 +1,6 @@ # Tutorial 5: Relationships & Hyperlinked APIs -At the moment relationships within our API are represented by using primary keys. In this part of the tutorial we'll improve the cohesion and discoverability of our API, by instead using hyperlinking for relationships. +At the moment relationships within our API are represented by using primary keys. In this part of the tutorial we'll improve the cohesion and discoverability of our API, by instead using hyperlinking for relationships. ## Creating an endpoint for the root of our API @@ -37,7 +37,7 @@ Instead of using a concrete generic view, we'll use the base class for represent class SnippetHighlight(generics.GenericAPIView): queryset = Snippet.objects.all() renderer_classes = (renderers.StaticHTMLRenderer,) - + def get(self, request, *args, **kwargs): snippet = self.get_object() return Response(snippet.highlighted) @@ -78,16 +78,16 @@ We can easily re-write our existing serializers to use hyperlinking. In your `sn class SnippetSerializer(serializers.HyperlinkedModelSerializer): owner = serializers.Field(source='owner.username') highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html') - + class Meta: model = Snippet fields = ('url', 'highlight', 'owner', 'title', 'code', 'linenos', 'language', 'style') - - + + class UserSerializer(serializers.HyperlinkedModelSerializer): snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail') - + class Meta: model = User fields = ('url', 'username', 'snippets') @@ -126,9 +126,9 @@ After adding all those names into our URLconf, our final `snippets/urls.py` file views.UserDetail.as_view(), name='user-detail') )) - + # Login and logout views for the browsable API - urlpatterns += patterns('', + urlpatterns += patterns('', url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), ) diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md index 8bf8c7f5..029b56a2 100644 --- a/docs/tutorial/quickstart.md +++ b/docs/tutorial/quickstart.md @@ -46,14 +46,14 @@ First up we're going to define some serializers in `quickstart/serializers.py` t from django.contrib.auth.models import User, Group from rest_framework import serializers - - + + class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User fields = ('url', 'username', 'email', 'groups') - - + + class GroupSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Group @@ -68,16 +68,16 @@ Right, we'd better write some views then. Open `quickstart/views.py` and get ty from django.contrib.auth.models import User, Group from rest_framework import viewsets from quickstart.serializers import UserSerializer, GroupSerializer - - + + class UserViewSet(viewsets.ModelViewSet): """ API endpoint that allows users to be viewed or edited. """ queryset = User.objects.all() serializer_class = UserSerializer - - + + class GroupViewSet(viewsets.ModelViewSet): """ API endpoint that allows groups to be viewed or edited. @@ -144,22 +144,22 @@ We're now ready to test the API we've built. Let's fire up the server from the We can now access our API, both from the command-line, using tools like `curl`... - bash: curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/ + bash: curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/ { - "count": 2, - "next": null, - "previous": null, + "count": 2, + "next": null, + "previous": null, "results": [ { - "email": "admin@example.com", - "groups": [], - "url": "http://127.0.0.1:8000/users/1/", + "email": "admin@example.com", + "groups": [], + "url": "http://127.0.0.1:8000/users/1/", "username": "admin" - }, + }, { - "email": "tom@example.com", - "groups": [ ], - "url": "http://127.0.0.1:8000/users/2/", + "email": "tom@example.com", + "groups": [ ], + "url": "http://127.0.0.1:8000/users/2/", "username": "tom" } ] -- cgit v1.2.3 From 61a1eaa4856dca3879010465fd0d60244450960e Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 18 Aug 2014 11:55:22 +0100 Subject: tabs -> spaces --- docs/tutorial/quickstart.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md index 0e60fa7c..98e5f439 100644 --- a/docs/tutorial/quickstart.md +++ b/docs/tutorial/quickstart.md @@ -6,8 +6,8 @@ We're going to create a simple API to allow admin users to view and edit the use Create a new Django project named `tutorial`, then start a new app called `quickstart`. - # Create the project directory - mkdir tutorial + # Create the project directory + mkdir tutorial cd tutorial # Create a virtualenv to isolate our package dependencies locally -- cgit v1.2.3