diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/api-guide/serializers.md | 29 | ||||
| -rw-r--r-- | docs/topics/release-notes.md | 12 | ||||
| -rw-r--r-- | docs/tutorial/1-serialization.md | 12 | ||||
| -rw-r--r-- | docs/tutorial/2-requests-and-responses.md | 8 | ||||
| -rw-r--r-- | docs/tutorial/3-class-based-views.md | 8 | ||||
| -rw-r--r-- | docs/tutorial/5-relationships-and-hyperlinked-apis.md | 2 |
6 files changed, 46 insertions, 25 deletions
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index c88b9b0c..ee7f72dd 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -47,7 +47,7 @@ The first part of serializer class defines the fields that get serialized/deseri We can now use `CommentSerializer` to serialize a comment, or list of comments. Again, using the `Serializer` class looks a lot like using a `Form` class. - serializer = CommentSerializer(instance=comment) + serializer = CommentSerializer(comment) serializer.data # {'email': u'leila@example.com', 'content': u'foo bar', 'created': datetime.datetime(2012, 8, 22, 16, 20, 9, 822774)} @@ -65,20 +65,29 @@ Deserialization is similar. First we parse a stream into python native datatype ...then we restore those native datatypes into a fully populated object instance. - serializer = CommentSerializer(data) + serializer = CommentSerializer(data=data) serializer.is_valid() # True serializer.object # <Comment object at 0x10633b2d0> >>> serializer.deserialize('json', stream) +When deserializing data, we can either create a new instance, or update an existing instance. + + serializer = CommentSerializer(data=data) # Create new instance + serializer = CommentSerializer(comment, data=data) # Update `instance` + ## Validation When deserializing data, you always need to call `is_valid()` before attempting to access the deserialized object. If any validation errors occur, the `.errors` and `.non_field_errors` properties will contain the resulting error messages. ### Field-level validation -You can specify custom field-level validation by adding `validate_<fieldname>()` methods to your `Serializer` subclass. These are analagous to `clean_<fieldname>` methods on Django forms, but accept slightly different arguments. They take a dictionary of deserialized attributes as a first argument, and the field name in that dictionary as a second argument (which will be either the name of the field or the value of the `source` argument to the field, if one was provided). Your `validate_<fieldname>` methods should either just return the attrs dictionary or raise a `ValidationError`. For example: +You can specify custom field-level validation by adding `.validate_<fieldname>` methods to your `Serializer` subclass. These are analagous to `.clean_<fieldname>` methods on Django forms, but accept slightly different arguments. + +They take a dictionary of deserialized attributes as a first argument, and the field name in that dictionary as a second argument (which will be either the name of the field or the value of the `source` argument to the field, if one was provided). + +Your `validate_<fieldname>` methods should either just return the `attrs` dictionary or raise a `ValidationError`. For example: from rest_framework import serializers @@ -88,16 +97,22 @@ You can specify custom field-level validation by adding `validate_<fieldname>()` def validate_title(self, attrs, source): """ - Check that the blog post is about Django + Check that the blog post is about Django. """ value = attrs[source] - if "Django" not in value: + if "django" not in value.lower(): raise serializers.ValidationError("Blog post is not about Django") return attrs -### Final cross-field validation +### Object-level validation + +To do any other validation that requires access to multiple fields, add a method called `.validate()` to your `Serializer` subclass. This method takes a single argument, which is the `attrs` dictionary. It should raise a `ValidationError` if necessary, or just return `attrs`. + +## Saving object state + +Serializers also include a `.save()` method that you can override if you want to provide a method of persisting the state of a deserialized object. The default behavior of the method is to simply call `.save()` on the deserialized object instance. -To do any other validation that requires access to multiple fields, add a method called `validate` to your `Serializer` subclass. This method takes a single argument, which is the `attrs` dictionary. It should raise a `ValidationError` if necessary, or just return `attrs`. +The generic views provided by REST framework call the `.save()` method when updating or creating entities. ## Dealing with nested objects diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 14d910bd..6c0a7d3c 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -4,8 +4,13 @@ > > — Eric S. Raymond, [The Cathedral and the Bazaar][cite]. -## Master +## 2.1.0 +**Date**: 5th Nov 2012 + +**Warning**: Please read [this thread][2.1.0-notes] regarding the `instance` and `data` keyword args before updating to 2.1.0. + +* **Serializer `instance` and `data` keyword args have their position swapped.** * Support Django's cache framework. * Minor field improvements. (Don't stringify dicts, more robust many-pk fields.) * Bugfixes (Support choice field in Browseable API) @@ -29,7 +34,7 @@ **Date**: 30th Oct 2012 * **Fix all of the things.** (Well, almost.) -* For more information please see the [2.0 migration guide][migration]. +* For more information please see the [2.0 announcement][announcement]. --- @@ -135,4 +140,5 @@ * Initial release. [cite]: http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s04.html -[migration]: migration.md
\ No newline at end of file +[2.1.0-notes]: https://groups.google.com/d/topic/django-rest-framework/Vv2M0CMY9bg/discussion +[announcement]: rest-framework-2-announcement.md
\ No newline at end of file diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 316a3c25..ba64f2aa 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -162,7 +162,7 @@ Okay, once we've got a few imports out of the way, let's create a code snippet t We've now got a few snippet instances to play with. Let's take a look at serializing one of those instances. - serializer = SnippetSerializer(instance=snippet) + serializer = SnippetSerializer(snippet) serializer.data # {'pk': 1, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'} @@ -181,7 +181,7 @@ Deserialization is similar. First we parse a stream into python native datatype ...then we restore those native datatypes into to a fully populated object instance. - serializer = SnippetSerializer(data) + serializer = SnippetSerializer(data=data) serializer.is_valid() # True serializer.object @@ -240,12 +240,12 @@ The root of our API is going to be a view that supports listing all the existing """ if request.method == 'GET': snippets = Snippet.objects.all() - serializer = SnippetSerializer(instance=snippets) + serializer = SnippetSerializer(snippets) return JSONResponse(serializer.data) elif request.method == 'POST': data = JSONParser().parse(request) - serializer = SnippetSerializer(data) + serializer = SnippetSerializer(data=data) if serializer.is_valid(): serializer.save() return JSONResponse(serializer.data, status=201) @@ -267,12 +267,12 @@ We'll also need a view which corresponds to an individual snippet, and can be us return HttpResponse(status=404) if request.method == 'GET': - serializer = SnippetSerializer(instance=snippet) + serializer = SnippetSerializer(snippet) return JSONResponse(serializer.data) elif request.method == 'PUT': data = JSONParser().parse(request) - serializer = SnippetSerializer(data, instance=snippet) + serializer = SnippetSerializer(snippet, data=data) if serializer.is_valid(): serializer.save() return JSONResponse(serializer.data) diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index a7c23cba..b29daf05 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -52,11 +52,11 @@ We don't need our `JSONResponse` class anymore, so go ahead and delete that. On """ if request.method == 'GET': snippets = Snippet.objects.all() - serializer = SnippetSerializer(instance=snippets) + serializer = SnippetSerializer(snippets) return Response(serializer.data) elif request.method == 'POST': - serializer = SnippetSerializer(request.DATA) + serializer = SnippetSerializer(data=request.DATA) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -77,11 +77,11 @@ Our instance view is an improvement over the previous example. It's a little mo return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': - serializer = SnippetSerializer(instance=snippet) + serializer = SnippetSerializer(snippet) return Response(serializer.data) elif request.method == 'PUT': - serializer = SnippetSerializer(request.DATA, instance=snippet) + serializer = SnippetSerializer(snippet, data=request.DATA) if serializer.is_valid(): serializer.save() return Response(serializer.data) diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index 91ef4038..eddf6311 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -20,11 +20,11 @@ We'll start by rewriting the root view as a class based view. All this involves """ def get(self, request, format=None): snippets = Snippet.objects.all() - serializer = SnippetSerializer(instance=snippets) + serializer = SnippetSerializer(snippets) return Response(serializer.data) def post(self, request, format=None): - serializer = SnippetSerializer(request.DATA) + serializer = SnippetSerializer(data=request.DATA) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -44,12 +44,12 @@ So far, so good. It looks pretty similar to the previous case, but we've got be def get(self, request, pk, format=None): snippet = self.get_object(pk) - serializer = SnippetSerializer(instance=snippet) + serializer = SnippetSerializer(snippet) return Response(serializer.data) def put(self, request, pk, format=None): snippet = self.get_object(pk) - serializer = SnippetSerializer(request.DATA, instance=snippet) + serializer = SnippetSerializer(snippet, data=request.DATA) if serializer.is_valid(): serializer.save() return Response(serializer.data) diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index 3113249b..98c45b82 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -167,7 +167,7 @@ We've reached the end of our tutorial. If you want to get more involved in the * Join the [REST framework discussion group][group], and help build the community. * Follow the author [on Twitter][twitter] and say hi. -**Now go build some awesome things.** +**Now go build awesome things.** [repo]: https://github.com/tomchristie/rest-framework-tutorial [sandbox]: http://restframework.herokuapp.com/ |
