diff options
| -rw-r--r-- | docs/api-guide/exceptions.md | 22 | ||||
| -rw-r--r-- | docs/api-guide/fields.md | 40 | ||||
| -rwxr-xr-x | docs/api-guide/generic-views.md | 2 | ||||
| -rw-r--r-- | docs/api-guide/parsers.md | 18 | ||||
| -rw-r--r-- | docs/api-guide/requests.md | 21 | ||||
| -rw-r--r-- | docs/api-guide/settings.md | 2 | ||||
| -rw-r--r-- | docs/api-guide/viewsets.md | 2 | ||||
| -rw-r--r-- | docs/topics/3.0-announcement.md | 2 | ||||
| -rw-r--r-- | docs/topics/release-notes.md | 122 | ||||
| -rw-r--r-- | docs/tutorial/2-requests-and-responses.md | 12 | ||||
| -rw-r--r-- | docs/tutorial/3-class-based-views.md | 4 | ||||
| -rw-r--r-- | rest_framework/request.py | 2 | 
12 files changed, 91 insertions, 158 deletions
| diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md index 8e0b1958..467ad970 100644 --- a/docs/api-guide/exceptions.md +++ b/docs/api-guide/exceptions.md @@ -100,7 +100,7 @@ For example, if your API relies on a third party service that may sometimes be u  **Signature:** `ParseError(detail=None)` -Raised if the request contains malformed data when accessing `request.DATA` or `request.FILES`. +Raised if the request contains malformed data when accessing `request.data`.  By default this exception results in a response with the HTTP status code "400 Bad Request". @@ -140,7 +140,7 @@ By default this exception results in a response with the HTTP status code "405 M  **Signature:** `UnsupportedMediaType(media_type, detail=None)` -Raised if there are no parsers that can handle the content type of the request data when accessing `request.DATA` or `request.FILES`. +Raised if there are no parsers that can handle the content type of the request data when accessing `request.data`.  By default this exception results in a response with the HTTP status code "415 Unsupported Media Type". @@ -152,5 +152,23 @@ Raised when an incoming request fails the throttling checks.  By default this exception results in a response with the HTTP status code "429 Too Many Requests". +## ValidationError + +**Signature:** `ValidationError(detail)` + +The `ValidationError` exception is slightly different from the other `APIException` classes: + +* The `detail` argument is mandatory, not optional. +* The `detail` argument may be a list or dictionary of error details, and may also be a nested data structure. +* By convention you should import the serializers module and use a fully qualified `ValidationError` style, in order to differentiate it from Django's built-in validation error. For example. `raise serializers.ValidationError('This field must be an integer value.')` + +The `ValidationError` class should be used for serializer and field validation, and by validator classes. It is also raised when calling `serializer.is_valid` with the `raise_exception` keyword argument: + +    serializer.is_valid(raise_exception=True) + +The generic views use the `raise_exception=True` flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above. + +By default this exception results in a response with the HTTP status code "400 Bad Request". +  [cite]: http://www.doughellmann.com/articles/how-tos/python-exception-handling/index.html  [authentication]: authentication.md diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 354ec966..68cdc622 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -22,7 +22,7 @@ Each serializer field class constructor takes at least these arguments.  Some Fi  The name of the attribute that will be used to populate the field.  May be a method that only takes a `self` argument, such as `Field(source='get_absolute_url')`, or may use dotted notation to traverse attributes, such as `Field(source='user.email')`. -The value `source='*'` has a special meaning, and is used to indicate that the entire object should be passed through to the field.  This can be useful for creating nested representations.  (See the implementation of the `PaginationSerializer` class for an example.) +The value `source='*'` has a special meaning, and is used to indicate that the entire object should be passed through to the field.  This can be useful for creating nested representations, or for fields which require access to the complete object in order to determine the output representation.  Defaults to the name of the field. @@ -45,25 +45,28 @@ Set to false if this field is not required to be present during deserialization.  Defaults to `True`. +### `allow_null` + +Normally an error will be raise if `None` is passed to a serializer field. Set this keyword argument to `True` if `None` should be considered a valid value. + +Defaults to `False` +  ### `default`  If set, this gives the default value that will be used for the field if no input value is supplied.  If not set the default behavior is to not populate the attribute at all.  May be set to a function or other callable, in which case the value will be evaluated each time it is used. +Note that setting a `default` value implies that the field is not required. Including both the `default` and `required` keyword arguments is invalid and will raise an error. +  ### `validators` -A list of Django validators that should be used to validate deserialized values. +A list of validator functions which should be applied to the incoming field input, and which either raise a validation error or simply return. Validator functions should typically raise `serializers.ValidationError`, but Django's built-in `ValidationError` is also supported for compatibility with validators defined in the Django codebase or third party Django packages.  ### `error_messages`  A dictionary of error codes to error messages. -### `widget` - -Used only if rendering the field to HTML. -This argument sets the widget that should be used to render the field. For more details, and a list of available widgets, see [the Django documentation on form widgets][django-widgets]. -  ### `label`  A short text string that may be used as the name of the field in HTML form fields or other descriptive elements. @@ -72,6 +75,29 @@ A short text string that may be used as the name of the field in HTML form field  A text string that may be used as a description of the field in HTML form fields or other descriptive elements. +### `initial` + +A value that should be used for pre-populating the value of HTML form fields. + +### `style` + +A dictionary of key-value pairs that can be used to control how renderers should render the field. The API for this should still be considered experimental, and will be formalized with the 3.1 release. + +Two options are currently used in HTML form generation, `'input_type'` and `'base_template'`. + +    # Use <input type="password"> for the input. +    password = serializers.CharField( +        style={'input_type': 'password'} +    ) + +    # Use a radio input instead of a select input. +    color_channel = serializers.ChoiceField( +        choices=['red', 'green', 'blue'] +        style = {'base_template': 'radio.html'} +    } + +**Note**: The `style` argument replaces the old-style version 2.x `widget` keyword argument. Because REST framework 3 now uses templated HTML form generation, the `widget` option that was used to support Django built-in widgets can no longer be supported. Version 3.1 is planned to include public API support for customizing HTML form generation. +  ---  # Generic Fields diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 648ece82..489b628f 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -352,7 +352,7 @@ You can then simply apply this mixin to a view or viewset anytime you need to ap          serializer_class = UserSerializer          lookup_fields = ('account', 'username') -Using custom mixins is a good option if you have custom behavior that needs to be used +Using custom mixins is a good option if you have custom behavior that needs to be used.  ## Creating custom base classes diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index 42d77b22..73e3a705 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -12,7 +12,7 @@ REST framework includes a number of built in Parser classes, that allow you to a  ## How the parser is determined -The set of valid parsers for a view is always defined as a list of classes.  When either `request.DATA` or `request.FILES` is accessed, REST framework will examine the `Content-Type` header on the incoming request, and determine which parser to use to parse the request content. +The set of valid parsers for a view is always defined as a list of classes.  When  `request.data` is accessed, REST framework will examine the `Content-Type` header on the incoming request, and determine which parser to use to parse the request content.  --- @@ -48,7 +48,7 @@ using the `APIView` class based views.          parser_classes = (YAMLParser,)          def post(self, request, format=None): -            return Response({'received data': request.DATA}) +            return Response({'received data': request.data})  Or, if you're using the `@api_view` decorator with function based views. @@ -58,7 +58,7 @@ Or, if you're using the `@api_view` decorator with function based views.          """          A view that can accept POST requests with YAML content.          """ -        return Response({'received data': request.DATA}) +        return Response({'received data': request.data})  --- @@ -92,7 +92,7 @@ Requires the `defusedxml` package to be installed.  ## FormParser -Parses HTML form content.  `request.DATA` will be populated with a `QueryDict` of data, `request.FILES` will be populated with an empty `QueryDict` of data. +Parses HTML form content.  `request.data` will be populated with a `QueryDict` of data.  You will typically want to use both `FormParser` and `MultiPartParser` together in order to fully support HTML form data. @@ -100,7 +100,7 @@ You will typically want to use both `FormParser` and `MultiPartParser` together  ## MultiPartParser -Parses multipart HTML form content, which supports file uploads.  Both `request.DATA` and `request.FILES` will be populated with a `QueryDict`. +Parses multipart HTML form content, which supports file uploads.  Both `request.data` will be populated with a `QueryDict`.  You will typically want to use both `FormParser` and `MultiPartParser` together in order to fully support HTML form data. @@ -108,7 +108,7 @@ You will typically want to use both `FormParser` and `MultiPartParser` together  ## FileUploadParser -Parses raw file upload content.  The `request.DATA` property will be an empty `QueryDict`, and `request.FILES` will be a dictionary with a single key `'file'` containing the uploaded file. +Parses raw file upload content.  The `request.data` property will be a dictionary with a single key `'file'` containing the uploaded file.  If the view used with `FileUploadParser` is called with a `filename` URL keyword argument, then that argument will be used as the filename.  If it is called without a `filename` URL keyword argument, then the client must set the filename in the `Content-Disposition` HTTP header.  For example `Content-Disposition: attachment; filename=upload.jpg`. @@ -126,7 +126,7 @@ If the view used with `FileUploadParser` is called with a `filename` URL keyword          parser_classes = (FileUploadParser,)          def put(self, request, filename, format=None): -            file_obj = request.FILES['file'] +            file_obj = request.data['file']              # ...              # do some staff with uploaded file              # ... @@ -139,7 +139,7 @@ If the view used with `FileUploadParser` is called with a `filename` URL keyword  To implement a custom parser, you should override `BaseParser`, set the `.media_type` property, and implement the `.parse(self, stream, media_type, parser_context)` method. -The method should return the data that will be used to populate the `request.DATA` property. +The method should return the data that will be used to populate the `request.data` property.  The arguments passed to `.parse()` are: @@ -161,7 +161,7 @@ By default this will include the following keys: `view`, `request`, `args`, `kwa  ## Example -The following is an example plaintext parser that will populate the `request.DATA` property with a string representing the body of the request. +The following is an example plaintext parser that will populate the `request.data` property with a string representing the body of the request.       class PlainTextParser(BaseParser):      """ diff --git a/docs/api-guide/requests.md b/docs/api-guide/requests.md index 8713fa2a..433d666c 100644 --- a/docs/api-guide/requests.md +++ b/docs/api-guide/requests.md @@ -14,26 +14,29 @@ REST framework's `Request` class extends the standard `HttpRequest`, adding supp  REST framework's Request objects provide flexible request parsing that allows you to treat requests with JSON data or other media types in the same way that you would normally deal with form data. -## .DATA +## .data -`request.DATA` returns the parsed content of the request body.  This is similar to the standard `request.POST` attribute except that: +`request.data` returns the parsed content of the request body.  This is similar to the standard `request.POST` and `request.FILES` attributes except that: +* It includes all parsed content, including *file and non-file* inputs.  * It supports parsing the content of HTTP methods other than `POST`, meaning that you can access the content of `PUT` and `PATCH` requests.  * It supports REST framework's flexible request parsing, rather than just supporting form data.  For example you can handle incoming JSON data in the same way that you handle incoming form data.  For more details see the [parsers documentation]. -## .FILES +## .query_params -`request.FILES` returns any uploaded files that may be present in the content of the request body.  This is the same as the standard `HttpRequest` behavior, except that the same flexible request parsing is used for `request.DATA`. +`request.query_params` is a more correctly named synonym for `request.GET`. -For more details see the [parsers documentation]. +For clarity inside your code, we recommend using `request.query_params` instead of the Django's standard `request.GET`. Doing so will help keep your codebase more correct and obvious - any HTTP method type may include query parameters, not just `GET` requests. -## .QUERY_PARAMS +## .DATA and .FILES -`request.QUERY_PARAMS` is a more correctly named synonym for `request.GET`. +The old-style version 2.x `request.data` and `request.FILES` attributes are still available, but are now pending deprecation in favor of the unified `request.data` attribute. + +## .QUERY_PARAMS -For clarity inside your code, we recommend using `request.QUERY_PARAMS` instead of the usual `request.GET`, as *any* HTTP method type may include query parameters. +The old-style version 2.x `request.QUERY_PARAMS` attribute is still available, but is now pending deprecation in favor of the more pythonic `request.query_params`.  ## .parsers @@ -43,7 +46,7 @@ You won't typically need to access this property.  --- -**Note:** If a client sends malformed content, then accessing `request.DATA` or `request.FILES` may raise a `ParseError`.  By default REST framework's `APIView` class or `@api_view` decorator will catch the error and return a `400 Bad Request` response. +**Note:** If a client sends malformed content, then accessing `request.data` may raise a `ParseError`.  By default REST framework's `APIView` class or `@api_view` decorator will catch the error and return a `400 Bad Request` response.  If a client sends a request with a content-type that cannot be parsed then a `UnsupportedMediaType` exception will be raised, which by default will be caught and return a `415 Unsupported Media Type` response. diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 0aa4b6a9..9005511b 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -51,7 +51,7 @@ Default:  #### DEFAULT_PARSER_CLASSES -A list or tuple of parser classes, that determines the default set of parsers used when accessing the `request.DATA` property. +A list or tuple of parser classes, that determines the default set of parsers used when accessing the `request.data` property.  Default: diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 9249d875..28186c64 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -124,7 +124,7 @@ For example:          @detail_route(methods=['post'])          def set_password(self, request, pk=None):              user = self.get_object() -            serializer = PasswordSerializer(data=request.DATA) +            serializer = PasswordSerializer(data=request.data)              if serializer.is_valid():                  user.set_password(serializer.data['password'])                  user.save() diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index 6a662326..f20a4296 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -865,7 +865,7 @@ Or modify it on an individual serializer field, using the `coerce_to_string` key          coerce_to_string=False      ) -The default JSON renderer will return float objects for uncoerced `Decimal` instances. This allows you to easily switch between string or float representations for decimals depending on your API design needs. +The default JSON renderer will return float objects for un-coerced `Decimal` instances. This allows you to easily switch between string or float representations for decimals depending on your API design needs.  ## Miscellaneous notes. diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 9fca949a..53187589 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -442,7 +442,7 @@ The security vulnerabilities only affect APIs which use the `XMLParser` class, b  * Bugfix: Validation errors instead of exceptions when related fields receive incorrect types.  * Bugfix: Handle ObjectDoesNotExist exception when serializing null reverse one-to-one -**Note**: Prior to 2.1.16, The Decimals would render in JSON using floating point if `simplejson` was installed, but otherwise render using string notation.  Now that use of `simplejson` has been deprecated, Decimals will consistently render using string notation.  See [#582] for more details. +**Note**: Prior to 2.1.16, The Decimals would render in JSON using floating point if `simplejson` was installed, but otherwise render using string notation.  Now that use of `simplejson` has been deprecated, Decimals will consistently render using string notation.  See [ticket 582](ticket-582) for more details.  ### 2.1.15 @@ -614,122 +614,7 @@ This change will not affect user code, so long as it's following the recommended  * **Fix all of the things.**  (Well, almost.)  * For more information please see the [2.0 announcement][announcement]. ---- - -## 0.4.x series - -### 0.4.0 - -* Supports Django 1.5. -* Fixes issues with 'HEAD' method. -* Allow views to specify template used by TemplateRenderer -* More consistent error responses -* Some serializer fixes -* Fix internet explorer ajax behavior -* Minor xml and yaml fixes -* Improve setup (e.g. use staticfiles, not the defunct ADMIN_MEDIA_PREFIX) -* Sensible absolute URL generation, not using hacky set_script_prefix - ---- - -## 0.3.x series - -### 0.3.3 - -* Added DjangoModelPermissions class to support `django.contrib.auth` style permissions. -* Use `staticfiles` for css files. -  - Easier to override.  Won't conflict with customized admin styles (e.g. grappelli) -* Templates are now nicely namespaced. -  - Allows easier overriding. -* Drop implied 'pk' filter if last arg in urlconf is unnamed. -  - Too magical.  Explicit is better than implicit. -* Saner template variable auto-escaping. -* Tidier setup.py -* Updated for URLObject 2.0 -* Bugfixes: -  - Bug with PerUserThrottling when user contains unicode chars. - -### 0.3.2 - -* Bugfixes: -  * Fix 403 for POST and PUT from the UI with UserLoggedInAuthentication (#115) -  * serialize_model method in serializer.py may cause wrong value (#73) -  * Fix Error when clicking OPTIONS button (#146) -  * And many other fixes -* Remove short status codes -  - Zen of Python: "There should be one-- and preferably only one --obvious way to do it." -* get_name, get_description become methods on the view - makes them overridable. -* Improved model mixin API - Hooks for build_query, get_instance_data, get_model, get_queryset, get_ordering - -### 0.3.1 - -* [not documented] - -### 0.3.0 - -* JSONP Support -* Bugfixes, including support for latest markdown release - ---- - -## 0.2.x series - -### 0.2.4 - -* Fix broken IsAdminUser permission. -* OPTIONS support. -* XMLParser. -* Drop mentions of Blog, BitBucket. - -### 0.2.3 - -* Fix some throttling bugs. -* ``X-Throttle`` header on throttling. -* Support for nesting resources on related models. - -### 0.2.2 - -* Throttling support complete. - -### 0.2.1 - -* Couple of simple bugfixes over 0.2.0 - -### 0.2.0 - -* Big refactoring changes since 0.1.0, ask on the discussion group if anything isn't clear. -  The public API has been massively cleaned up.  Expect it to be fairly stable from here on in. - -* ``Resource`` becomes decoupled into ``View`` and ``Resource``, your views should now inherit from ``View``, not ``Resource``. - -* The handler functions on views ``.get() .put() .post()`` etc, no longer have the ``content`` and ``auth`` args. -  Use ``self.CONTENT`` inside a view to access the deserialized, validated content. -  Use ``self.user`` inside a view to access the authenticated user. - -* ``allowed_methods`` and ``anon_allowed_methods`` are now defunct.  if a method is defined, it's available. -  The ``permissions`` attribute on a ``View`` is now used to provide generic permissions checking. -  Use permission classes such as ``FullAnonAccess``, ``IsAuthenticated`` or ``IsUserOrIsAnonReadOnly`` to set the permissions. - -* The ``authenticators`` class becomes ``authentication``.  Class names change to ``Authentication``. - -* The ``emitters`` class becomes ``renderers``.  Class names change to ``Renderers``. - -* ``ResponseException`` becomes ``ErrorResponse``. - -* The mixin classes have been nicely refactored, the basic mixins are now ``RequestMixin``, ``ResponseMixin``, ``AuthMixin``, and ``ResourceMixin`` -  You can reuse these mixin classes individually without using the ``View`` class. - ---- - -## 0.1.x series - -### 0.1.1 - -* Final build before pulling in all the refactoring changes for 0.2, in case anyone needs to hang on to 0.1. - -### 0.1.0 - -* Initial release. +For older release notes, [please see the GitHub repo](old-release-notes).  [cite]: http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s04.html  [deprecation-policy]: #deprecation-policy @@ -742,5 +627,6 @@ This change will not affect user code, so long as it's following the recommended  [staticfiles13]: https://docs.djangoproject.com/en/1.3/howto/static-files/#with-a-template-tag  [2.1.0-notes]: https://groups.google.com/d/topic/django-rest-framework/Vv2M0CMY9bg/discussion  [announcement]: rest-framework-2-announcement.md -[#582]: https://github.com/tomchristie/django-rest-framework/issues/582 +[ticket-582]: https://github.com/tomchristie/django-rest-framework/issues/582  [rfc-6266]: http://tools.ietf.org/html/rfc6266#section-4.3 +[old-release-notes]: https://github.com/tomchristie/django-rest-framework/blob/2.4.4/docs/topics/release-notes.md#04x-series diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index 136b0135..f377c712 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -5,10 +5,10 @@ Let's introduce a couple of essential building blocks.  ## Request objects -REST framework introduces a `Request` object that extends the regular `HttpRequest`, and provides more flexible request parsing.  The core functionality of the `Request` object is the `request.DATA` attribute, which is similar to `request.POST`, but more useful for working with Web APIs. +REST framework introduces a `Request` object that extends the regular `HttpRequest`, and provides more flexible request parsing.  The core functionality of the `Request` object is the `request.data` attribute, which is similar to `request.POST`, but more useful for working with Web APIs.      request.POST  # Only handles form data.  Only works for 'POST' method. -    request.DATA  # Handles arbitrary data.  Works for 'POST', 'PUT' and 'PATCH' methods. +    request.data  # Handles arbitrary data.  Works for 'POST', 'PUT' and 'PATCH' methods.  ## Response objects @@ -29,7 +29,7 @@ REST framework provides two wrappers you can use to write API views.  These wrappers provide a few bits of functionality such as making sure you receive `Request` instances in your view, and adding context to `Response` objects so that content negotiation can be performed. -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. +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 @@ -55,7 +55,7 @@ We don't need our `JSONResponse` class in `views.py` anymore, so go ahead and de              return Response(serializer.data)          elif request.method == 'POST': -            serializer = SnippetSerializer(data=request.DATA) +            serializer = SnippetSerializer(data=request.data)              if serializer.is_valid():                  serializer.save()                  return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -80,7 +80,7 @@ Here is the view for an individual snippet, in the `views.py` module.              return Response(serializer.data)          elif request.method == 'PUT': -            serializer = SnippetSerializer(snippet, data=request.DATA) +            serializer = SnippetSerializer(snippet, data=request.data)              if serializer.is_valid():                  serializer.save()                  return Response(serializer.data) @@ -92,7 +92,7 @@ Here is the view for an individual snippet, in the `views.py` module.  This should all feel very familiar - it is not a lot different from working with regular Django views. -Notice that we're no longer explicitly tying our requests or responses to a given content type.  `request.DATA` can handle incoming `json` requests, but it can also handle `yaml` and other formats.  Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us. +Notice that we're no longer explicitly tying our requests or responses to a given content type.  `request.data` can handle incoming `json` requests, but it can also handle `yaml` and other formats.  Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us.  ## Adding optional format suffixes to our URLs diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index 382f078a..0a9ea3f1 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -24,7 +24,7 @@ We'll start by rewriting the root view as a class based view.  All this involves              return Response(serializer.data)          def post(self, request, format=None): -            serializer = SnippetSerializer(data=request.DATA) +            serializer = SnippetSerializer(data=request.data)              if serializer.is_valid():                  serializer.save()                  return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -49,7 +49,7 @@ So far, so good.  It looks pretty similar to the previous case, but we've got be          def put(self, request, pk, format=None):              snippet = self.get_object(pk) -            serializer = SnippetSerializer(snippet, data=request.DATA) +            serializer = SnippetSerializer(snippet, data=request.data)              if serializer.is_valid():                  serializer.save()                  return Response(serializer.data) diff --git a/rest_framework/request.py b/rest_framework/request.py index 096b3042..d7e74674 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -310,7 +310,7 @@ class Request(object):      def _load_data_and_files(self):          """ -        Parses the request content into self.DATA and self.FILES. +        Parses the request content into `self.data`.          """          if not _hasattr(self, '_content_type'):              self._load_method_and_content_type() | 
