From 674c9029c1b0f3680bfc04dd87b58f9bd21988de Mon Sep 17 00:00:00 2001 From: Richard Wackerbarth Date: Fri, 4 Jan 2013 05:46:30 -0600 Subject: Imply an additional element in infinite lists This is to allow the addition of elements without having to change existing lines of code --- docs/tutorial/1-serialization.md | 4 ++-- docs/tutorial/2-requests-and-responses.md | 2 +- docs/tutorial/3-class-based-views.md | 2 +- docs/tutorial/4-authentication-and-permissions.md | 4 ++-- docs/tutorial/5-relationships-and-hyperlinked-apis.md | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index e61fb946..c8db8f24 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -60,7 +60,7 @@ We'll also need to add our new `snippets` app and the `rest_framework` app to `I INSTALLED_APPS = ( ... 'rest_framework', - 'snippets' + 'snippets', ) We also need to wire up the root urlconf, in the `tutorial/urls.py` file, to include our snippet app's URLs. @@ -288,7 +288,7 @@ Finally we need to wire these views up. Create the `snippets/urls.py` file: urlpatterns = patterns('snippets.views', url(r'^snippets/$', 'snippet_list'), - url(r'^snippets/(?P[0-9]+)/$', 'snippet_detail') + url(r'^snippets/(?P[0-9]+)/$', 'snippet_detail'), ) It's worth noting that there are a couple of edge cases we're not dealing with properly at the moment. If we send malformed `json`, or if a request is made with a method that the view doesn't handle, then we'll end up with a 500 "server error" response. Still, this'll do for now. diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index 08cf91cd..cdf6c13f 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -117,7 +117,7 @@ Now update the `urls.py` file slightly, to append a set of `format_suffix_patter urlpatterns = patterns('snippets.views', url(r'^snippets/$', 'snippet_list'), - url(r'^snippets/(?P[0-9]+)$', 'snippet_detail') + url(r'^snippets/(?P[0-9]+)$', 'snippet_detail'), ) urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index b115b022..290ea5e9 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -70,7 +70,7 @@ We'll also need to refactor our URLconf slightly now we're using class based vie urlpatterns = patterns('', url(r'^snippets/$', views.SnippetList.as_view()), - url(r'^snippets/(?P[0-9]+)/$', views.SnippetDetail.as_view()) + url(r'^snippets/(?P[0-9]+)/$', views.SnippetDetail.as_view()), ) urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 9576a7f0..5793d38e 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -77,7 +77,7 @@ We'll also add a couple of views. We'd like to just use read-only views for the Finally we need to add those views into the API, by referencing them from the URL conf. url(r'^users/$', views.UserList.as_view()), - url(r'^users/(?P[0-9]+)/$', views.UserInstance.as_view()) + url(r'^users/(?P[0-9]+)/$', views.UserInstance.as_view()), ## Associating Snippets with Users @@ -134,7 +134,7 @@ And, at the end of the file, add a pattern to include the login and logout views urlpatterns += patterns('', url(r'^api-auth/', include('rest_framework.urls', - namespace='rest_framework')) + namespace='rest_framework')), ) The `r'^api-auth/'` part of pattern can actually be whatever URL you want to use. The only restriction is that the included urls must use the `'rest_framework'` namespace. diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index 216ca433..c4c03495 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -116,7 +116,7 @@ After adding all those names into our URLconf, our final `'urls.py'` file should url(r'^snippets/(?P[0-9]+)/$', views.SnippetDetail.as_view(), name='snippet-detail'), - url(r'^snippets/(?P[0-9]+)/highlight/$' + url(r'^snippets/(?P[0-9]+)/highlight/$', views.SnippetHighlight.as_view(), name='snippet-highlight'), url(r'^users/$', @@ -130,7 +130,7 @@ After adding all those names into our URLconf, our final `'urls.py'` file should # Login and logout views for the browsable API urlpatterns += patterns('', url(r'^api-auth/', include('rest_framework.urls', - namespace='rest_framework')) + namespace='rest_framework')), ) ## Adding pagination -- cgit v1.2.3 From 8efd9563a6d207619ebbd066292fa910023189ae Mon Sep 17 00:00:00 2001 From: Richard Wackerbarth Date: Fri, 4 Jan 2013 05:47:27 -0600 Subject: Some comment on the tutorial repository --- docs/tutorial/1-serialization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index c8db8f24..d12f7935 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -8,7 +8,7 @@ The tutorial is fairly in-depth, so you should probably get a cookie and a cup o --- -**Note**: The final code for this tutorial is available in the [tomchristie/rest-framework-tutorial][repo] repository on GitHub. There is also a sandbox version for testing, [available here][sandbox]. +**Note**: The code for this tutorial is available in the [tomchristie/rest-framework-tutorial][repo] repository on GitHub. As pieces of code are introduced, they are committed to this repository. The completed implementation is also online as a sandbox version for testing, [available here][sandbox]. --- @@ -73,7 +73,7 @@ Okay, we're ready to roll. ## Creating a model to work with -For the purposes of this tutorial we're going to start by creating a simple `Snippet` model that is used to store code snippets. Go ahead and edit the `snippets` app's `models.py` file. +For the purposes of this tutorial we're going to start by creating a simple `Snippet` model that is used to store code snippets. Go ahead and edit the `snippets` app's `models.py` file. Note: Good programming practices include comments. Although you will find them in our repository version of this tutorial code, we have omitted them here to focus on the code itself. from django.db import models from pygments.lexers import get_all_lexers -- cgit v1.2.3 From 12efd78fcf40ea8acf95259ffc5269bd9f360d2f Mon Sep 17 00:00:00 2001 From: Richard Wackerbarth Date: Wed, 9 Jan 2013 11:19:12 -0600 Subject: Bringing up the Web API --- docs/tutorial/1-serialization.md | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index d12f7935..28aaea4d 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -295,9 +295,38 @@ It's worth noting that there are a couple of edge cases we're not dealing with p ## Testing our first attempt at a Web API -**TODO: Describe using runserver and making example requests from console** +Now we can start up a sample server that serves our snippets. -**TODO: Describe opening in a web browser and viewing json output** +Quit out of the shell + + quit() + +and start up Django's development server + + python manage.py runserver + + Validating models... + + 0 errors found + Django version 1.4.3, using settings 'tutorial.settings' + Development server is running at http://127.0.0.1:8000/ + Quit the server with CONTROL-C. + +In another terminal window, we can test the server. + +We can get a list of all of the snippets (we only have one at the moment) + + curl http://127.0.0.1:8000/snippets/ + + [{"id": 1, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"}] + +or we can get a particular snippet by referencing its id + + curl http://127.0.0.1:8000/snippets/1/ + + {"id": 1, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"} + +Similarly, you can have the same json displayed by referencing these URLs from your favorite web browser. ## Where are we now -- cgit v1.2.3 From 7dd5c56f225c7fe97a23101eea1bb839110d8ed2 Mon Sep 17 00:00:00 2001 From: Richard Wackerbarth Date: Thu, 10 Jan 2013 16:16:30 -0600 Subject: Make the whitespace uniform --- docs/tutorial/1-serialization.md | 3 --- docs/tutorial/2-requests-and-responses.md | 3 --- 2 files changed, 6 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 28aaea4d..db6db2da 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -202,8 +202,6 @@ Open the file `snippets/serializers.py` again, and edit the `SnippetSerializer` model = Snippet fields = ('id', 'title', 'code', 'linenos', 'language', 'style') - - ## Writing regular Django views using our Serializer Let's see how we can write some API views using our new Serializer class. @@ -229,7 +227,6 @@ Edit the `snippet/views.py` file, and add the following. kwargs['content_type'] = 'application/json' super(JSONResponse, self).__init__(content, **kwargs) - The root of our API is going to be a view that supports listing all the existing snippets, or creating a new snippet. @csrf_exempt diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index cdf6c13f..340ea28e 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -31,7 +31,6 @@ These wrappers provide a few bits of functionality such as making sure you recei 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. - ## Pulling it all together Okay, let's go ahead and start using these new components to write a few views. @@ -63,7 +62,6 @@ We don't need our `JSONResponse` class anymore, so go ahead and delete that. On else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - 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. Here is the view for an individual snippet. @@ -138,7 +136,6 @@ Because the API chooses a return format based on what the client asks for, it wi See the [browsable api][browseable-api] topic for more information about the browsable API feature and how to customize it. - ## What's next? In [tutorial part 3][tut-3], we'll start using class based views, and see how generic views reduce the amount of code we need to write. -- cgit v1.2.3 From 0987bed2f74f69eccba181303689197e54836288 Mon Sep 17 00:00:00 2001 From: Richard Wackerbarth Date: Fri, 11 Jan 2013 14:04:13 -0600 Subject: Minor gramatical correction --- docs/tutorial/4-authentication-and-permissions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 5793d38e..f6daebb7 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -29,7 +29,7 @@ And now we can add a `.save()` method to our model class: def save(self, *args, **kwargs): """ - Use the `pygments` library to create an highlighted HTML + Use the `pygments` library to create a highlighted HTML representation of the code snippet. """ lexer = get_lexer_by_name(self.language) -- cgit v1.2.3 From 08943c3e0aad30b2f9f6b8146daa80117b7adfb3 Mon Sep 17 00:00:00 2001 From: Richard Wackerbarth Date: Sun, 13 Jan 2013 10:49:49 -0600 Subject: Format extensions have already been introduced. If format extensions are used, they must be used in the creation of the reverse URLs.--- docs/tutorial/5-relationships-and-hyperlinked-apis.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (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 c4c03495..27898f7b 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -15,8 +15,8 @@ Right now we have endpoints for 'snippets' and 'users', but we don't have a sing @api_view(('GET',)) def api_root(request, format=None): return Response({ - 'users': reverse('user-list', request=request), - 'snippets': reverse('snippet-list', request=request) + 'users': reverse('user-list', request=request, format=format), + 'snippets': reverse('snippet-list', request=request, format=format) }) Notice that we're using REST framework's `reverse` function in order to return fully-qualified URLs. -- cgit v1.2.3 From 79f635e0ddeee6647a9c6f8937953052b17f6ff8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 15 Jan 2013 09:33:24 +0000 Subject: Modify tutorial to work with pygments 1.6rc. Fixes #581. --- docs/tutorial/1-serialization.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index db6db2da..d3ada9e3 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -78,9 +78,10 @@ For the purposes of this tutorial we're going to start by creating a simple `Sni from django.db import models from pygments.lexers import get_all_lexers from pygments.styles import get_all_styles - - LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in get_all_lexers()]) - STYLE_CHOICES = sorted((item, item) for item in list(get_all_styles())) + + 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): -- cgit v1.2.3 From af3fd098459fb559788735cb6b49a7108e11b18e Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 19 Jan 2013 15:31:21 +0000 Subject: Tweak imports in tutorial. Fixes #597. --- docs/tutorial/1-serialization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index d3ada9e3..f5ff167f 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -109,7 +109,7 @@ The first thing we need to get started on our Web API is provide a way of serial from django.forms import widgets from rest_framework import serializers - from snippets import models + from snippets.models import Snippet class SnippetSerializer(serializers.Serializer): @@ -138,7 +138,7 @@ The first thing we need to get started on our Web API is provide a way of serial return instance # Create new instance - return models.Snippet(**attrs) + 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. -- cgit v1.2.3 From 2c76212e5454efa4d4d02c7051055c7957497d52 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sun, 20 Jan 2013 16:38:32 +0000 Subject: Add missing import to tutorial. Fixes #599 --- docs/tutorial/4-authentication-and-permissions.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/tutorial') diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index f6daebb7..35aca8c6 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -54,6 +54,8 @@ You might also want to create a few different users, to use for testing the API. Now that we've got some users to work with, we'd better add representations of those users to our API. Creating a new serializer is easy: + from django.contrib.auth.models import User + class UserSerializer(serializers.ModelSerializer): snippets = serializers.ManyPrimaryKeyRelatedField() @@ -188,4 +190,4 @@ We've now got a fairly fine-grained set of permissions on our Web API, and end p In [part 5][tut-5] of the tutorial we'll look at how we can tie everything together by creating an HTML endpoint for our hightlighted snippets, and improve the cohesion of our API by using hyperlinking for the relationships within the system. -[tut-5]: 5-relationships-and-hyperlinked-apis.md \ No newline at end of file +[tut-5]: 5-relationships-and-hyperlinked-apis.md -- cgit v1.2.3