From a3ace366db4c664c88bf76b10b40b4c576c130dd Mon Sep 17 00:00:00 2001 From: Pavel Savchenko Date: Wed, 31 Oct 2012 00:37:30 +0200 Subject: [PATCH] using 'pk' in fields throws KeyError add missing imports Browsable API seems to be working fine with FBV's (2.0.0) removing snippets from the URI doesn't make sense remain consistent in using SnippetDetail --- docs/tutorial/1-serialization.md | 2 +- docs/tutorial/2-requests-and-responses.md | 2 -- docs/tutorial/3-class-based-views.md | 4 ++-- docs/tutorial/4-authentication-and-permissions.md | 12 ++++++++---- .../tutorial/5-relationships-and-hyperlinked-apis.md | 7 +++++-- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 5cf16a67f..316a3c255 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -201,7 +201,7 @@ Open the file `snippets/serializers.py` again, and edit the `SnippetSerializer` class SnippetSerializer(serializers.ModelSerializer): class Meta: model = Snippet - fields = ('pk', 'title', 'code', 'linenos', 'language', 'style') + fields = ('id', 'title', 'code', 'linenos', 'language', 'style') diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index 938739fa6..a7c23cba6 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -130,8 +130,6 @@ Go ahead and test the API from the command line, as we did in [tutorial part 1][ Now go and open the API in a web browser, by visiting [http://127.0.0.1:8000/snippets/][devserver]." -**Note: Right now the Browseable API only works with the CBV's. Need to fix that.** - ### Browsability Because the API chooses a return format based on what the client asks for, it will, by default, return an HTML-formatted representation of the resource when that resource is requested by a browser. This allows for the API to be easily browsable and usable by humans. diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index f27b5af01..a31dccb2f 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -69,8 +69,8 @@ We'll also need to refactor our URLconf slightly now we're using class based vie from snippetpost import views urlpatterns = patterns('', - url(r'^$', views.SnippetList.as_view()), - url(r'^(?P[0-9]+)$', views.SnippetDetail.as_view()) + url(r'^snippets/$', views.SnippetList.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 b0ed8f2a2..f85250bea 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -59,7 +59,7 @@ Now that we've got some users to work with, we'd better add representations of t class Meta: model = User - fields = ('pk', 'username', 'snippets') + fields = ('id', 'username', 'snippets') Because `'snippets'` is a *reverse* relationship on the User model, it will not be included by default when using the `ModelSerializer` class, so we've needed to add an explicit field for it. @@ -85,7 +85,7 @@ Right now, if we created a code snippet, there'd be no way of associating the us The way we deal with that is by overriding a `.pre_save()` method on our snippet views, that allows us to handle any information that is implicit in the incoming request or requested URL. -On **both** the `SnippetList` and `SnippetInstance` view classes, add the following method: +On **both** the `SnippetList` and `SnippetDetail` view classes, add the following method: def pre_save(self, obj): obj.owner = self.request.user @@ -112,7 +112,11 @@ Now that code snippets are associated with users we want to make sure that only REST framework includes a number of permission classes that we can use to restrict who can access a given view. In this case the one we're looking for is `IsAuthenticatedOrReadOnly`, which will ensure that authenticated requests get read-write access, and unauthenticated requests get read-only access. -Add the following property to **both** the `SnippetList` and `SnippetInstance` view classes. +First add the following import in the views module + + from rest_framework import permissions + +Then, add the following property to **both** the `SnippetList` and `SnippetDetail` view classes. permission_classes = (permissions.IsAuthenticatedOrReadOnly,) @@ -169,7 +173,7 @@ In the snippets app, create a new file, `permissions.py` # Write permissions are only allowed to the owner of the snippet return obj.owner == request.user -Now we can add that custom permission to our snippet instance endpoint, by editing the `permission_classes` property on the `SnippetInstance` class: +Now we can add that custom permission to our snippet instance endpoint, by editing the `permission_classes` property on the `SnippetDetail` class: permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index 1f663745d..a666ad828 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -29,7 +29,10 @@ 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 concreate 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. +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 class SnippetHighlight(generics.SingleObjectAPIView): model = Snippet @@ -111,7 +114,7 @@ After adding all those names into our URLconf, our final `'urls.py'` file should views.SnippetList.as_view(), name='snippet-list'), url(r'^snippets/(?P[0-9]+)/$', - views.SnippetInstance.as_view(), + views.SnippetDetail.as_view(), name='snippet-detail'), url(r'^snippets/(?P[0-9]+)/highlight/$' views.SnippetHighlight.as_view(),