diff options
Diffstat (limited to 'docs/tutorial/4-authentication-and-permissions.md')
| -rw-r--r-- | docs/tutorial/4-authentication-and-permissions.md | 22 | 
1 files changed, 13 insertions, 9 deletions
| diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 74ad9a55..4e4edeea 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -44,7 +44,9 @@ 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 +    rm -r snippets/migrations +    python manage.py makemigrations snippets +    python manage.py migrate  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. @@ -92,24 +94,26 @@ Finally we need to add those views into the API, by referencing them from the UR  Right now, if we created a code snippet, there'd be no way of associating the user that created the snippet, with the snippet instance.  The user isn't sent as part of the serialized representation, but is instead a property of the incoming request. -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. +The way we deal with that is by overriding a `.perform_create()` method on our snippet views, that allows us to modify how the instance save is managed, and handle any information that is implicit in the incoming request or requested URL. -On **both** the `SnippetList` and `SnippetDetail` view classes, add the following method: +On the `SnippetList` view class, add the following method: -    def pre_save(self, obj): -        obj.owner = self.request.user +    def perform_create(self, serializer): +        serializer.save(owner=self.request.user) + +The `create()` method of our serializer will now be passed an additional `'owner'` field, along with the validated data from the request.  ## Updating our serializer  Now that snippets are associated with the user that created them, let's update our `SnippetSerializer` to reflect that.  Add the following field to the serializer definition in `serializers.py`: -    owner = serializers.Field(source='owner.username') +    owner = serializers.ReadOnlyField(source='owner.username')  **Note**: Make sure you also add `'owner',` to the list of fields in the inner `Meta` class.  This field is doing something quite interesting.  The `source` argument controls which attribute is used to populate a field, and can point at any attribute on the serialized instance.  It can also take the dotted notation shown above, in which case it will traverse the given attributes, in a similar way as it is used with Django's template language. -The field we've added is the untyped `Field` class, in contrast to the other typed fields, such as `CharField`, `BooleanField` etc...  The untyped `Field` is always read-only, and will be used for serialized representations, but will not be used for updating model instances when they are deserialized. +The field we've added is the untyped `ReadOnlyField` class, in contrast to the other typed fields, such as `CharField`, `BooleanField` etc...  The untyped `ReadOnlyField` is always read-only, and will be used for serialized representations, but will not be used for updating model instances when they are deserialized. We could have also used `CharField(read_only=True)` here.  ## Adding required permissions to views @@ -137,10 +141,10 @@ Add the following import at the top of the file:  And, at the end of the file, add a pattern to include the login and logout views for the browsable API. -    urlpatterns += patterns('', +    urlpatterns += [          url(r'^api-auth/', include('rest_framework.urls',                                     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. | 
