diff options
| author | Tom Christie | 2014-11-28 09:57:02 +0000 |
|---|---|---|
| committer | Tom Christie | 2014-11-28 09:57:02 +0000 |
| commit | d4b8e356b952137760bf33750b17895526d6151e (patch) | |
| tree | cb4428b2967582dd8ca50cb1bcd1f7bb95b1fe5f /docs/topics | |
| parent | d2d7e1dfde2a62ee8f6d904368dbd6581de278c9 (diff) | |
| parent | 34ca8cd2a5c030d9acc89720876ba9583c1dc988 (diff) | |
| download | django-rest-framework-d4b8e356b952137760bf33750b17895526d6151e.tar.bz2 | |
Merge branch '3.0-docs'
Diffstat (limited to 'docs/topics')
| -rw-r--r-- | docs/topics/3.0-announcement.md | 54 | ||||
| -rw-r--r-- | docs/topics/browsable-api.md | 33 | ||||
| -rw-r--r-- | docs/topics/release-notes.md | 122 |
3 files changed, 64 insertions, 145 deletions
diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index 6a662326..9087e2ae 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -199,6 +199,33 @@ Alternatively if you want the errors to be against a specific field, use a dicti This ensures you can still write validation that compares all the input fields, but that marks the error against a particular field. +#### Removal of `transform_<field_name>`. + +The under-used `transform_<field_name>` on serializer classes is no longer provided. Instead you should just override `to_representation()` if you need to apply any modifications to the representation style. + +For example: + + def to_representation(self, instance): + ret = super(UserSerializer, self).to_representation(instance) + ret['username'] = ret['username'].lower() + return ret + +Dropping the extra point of API means there's now only one right way to do things. This helps with repetition and reinforcement of the core API, rather than having multiple differing approaches. + +If you absolutely need to preserve `transform_<field_name>` behavior, for example, in order to provide a simpler 2.x to 3.0 upgrade, you can use a mixin, or serializer base class that add the behavior back in. For example: + + class BaseModelSerializer(ModelSerializer): + """ + A custom ModelSerializer class that preserves 2.x style `transform_<field_name>` behavior. + """ + def to_representation(self, instance): + ret = super(BaseModelSerializer, self).to_representation(instance) + for key, value in ret.items(): + method = getattr(self, 'transform_' + key, None) + if method is not None: + ret[key] = method(value) + return ret + #### Differences between ModelSerializer validation and ModelForm. This change also means that we no longer use the `.full_clean()` method on model instances, but instead perform all validation explicitly on the serializer. This gives a cleaner separation, and ensures that there's no automatic validation behavior on `ModelSerializer` classes that can't also be easily replicated on regular `Serializer` classes. @@ -386,7 +413,11 @@ There are four methods that can be overridden, depending on what functionality y * `.to_representation()` - Override this to support serialization, for read operations. * `.to_internal_value()` - Override this to support deserialization, for write operations. -* `.create()` and `.update()` - Overide either or both of these to support saving instances. +* `.create()` and `.update()` - Override either or both of these to support saving instances. + +Because this class provides the same interface as the `Serializer` class, you can use it with the existing generic class based views exactly as you would for a regular `Serializer` or `ModelSerializer`. + +The only difference you'll notice when doing so is the `BaseSerializer` classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input. ##### Read-only `BaseSerializer` classes. @@ -471,7 +502,7 @@ Here's a complete example of our previous `HighScoreSerializer`, that's been upd The `BaseSerializer` class is also useful if you want to implement new generic serializer classes for dealing with particular serialization styles, or for integrating with alternative storage backends. -The following class is an example of a generic serializer that can handle coercing aribitrary objects into primitive representations. +The following class is an example of a generic serializer that can handle coercing arbitrary objects into primitive representations. class ObjectSerializer(serializers.BaseSerializer): """ @@ -491,12 +522,12 @@ The following class is an example of a generic serializer that can handle coerci # Primitive types can be passed through unmodified. output[attribute_name] = attribute elif isinstance(attribute, list): - # Recursivly deal with items in lists. + # Recursively deal with items in lists. output[attribute_name] = [ self.to_representation(item) for item in attribute ] elif isinstance(attribute, dict): - # Recursivly deal with items in dictionarys. + # Recursively deal with items in dictionaries. output[attribute_name] = { str(key): self.to_representation(value) for key, value in attribute.items() @@ -544,6 +575,19 @@ The `default` argument is also available and always implies that the field is no The previous field implementations did not forcibly coerce returned values into the correct type in many cases. For example, an `IntegerField` would return a string output if the attribute value was a string. We now more strictly coerce to the correct return type, leading to more constrained and expected behavior. +#### Removal of `.validate()`. + +The `.validate()` method is now removed from field classes. This method was in any case undocumented and not public API. You should instead simply override `to_internal_value()`. + + class UppercaseCharField(serializers.CharField): + def to_internal_value(self, data): + value = super(UppercaseCharField, self).to_internal_value(data) + if value != value.upper(): + raise serializers.ValidationError('The input should be uppercase only.') + return value + +Previously validation errors could be raised in either `.to_native()` or `.validate()`, making it non-obvious which should be used. Providing only a single point of API ensures more repetition and reinforcement of the core API. + #### The `ListField` class. The `ListField` class has now been added. This field validates list input. It takes a `child` keyword argument which is used to specify the field used to validate each item in the list. For example: @@ -865,7 +909,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/browsable-api.md b/docs/topics/browsable-api.md index ad812f4b..2879db74 100644 --- a/docs/topics/browsable-api.md +++ b/docs/topics/browsable-api.md @@ -130,34 +130,24 @@ You can override the `BrowsableAPIRenderer.get_context()` method to customise th For more advanced customization, such as not having a Bootstrap basis or tighter integration with the rest of your site, you can simply choose not to have `api.html` extend `base.html`. Then the page content and capabilities are entirely up to you. -#### Autocompletion +#### Handling `ChoiceField` with large numbers of items. -When a `ChoiceField` has too many items, rendering the widget containing all the options can become very slow, and cause the browsable API rendering to perform poorly. One solution is to replace the selector by an autocomplete widget, that only loads and renders a subset of the available options as needed. +When a relationship or `ChoiceField` has too many items, rendering the widget containing all the options can become very slow, and cause the browsable API rendering to perform poorly. -There are [a variety of packages for autocomplete widgets][autocomplete-packages], such as [django-autocomplete-light][django-autocomplete-light]. To setup `django-autocomplete-light`, follow the [installation documentation][django-autocomplete-light-install], add the the following to the `api.html` template: +The simplest option in this case is to replace the select input with a standard text input. For example: - {% block script %} - {{ block.super }} - {% include 'autocomplete_light/static.html' %} - {% endblock %} - -You can now add the `autocomplete_light.ChoiceWidget` widget to the serializer field. - - import autocomplete_light + author = serializers.HyperlinkedRelatedField( + queryset=User.objects.all(), + style={'base_template': 'input.html'} + ) - class BookSerializer(serializers.ModelSerializer): - author = serializers.ChoiceField( - widget=autocomplete_light.ChoiceWidget('AuthorAutocomplete') - ) +#### Autocomplete - class Meta: - model = Book - ---- +An alternative, but more complex option would be to replace the input with an autocomplete widget, that only loads and renders a subset of the available options as needed. If you need to do this you'll need to do some work to build a custom autocomplete HTML template yourself. -![Autocomplete][autocomplete-image] +There are [a variety of packages for autocomplete widgets][autocomplete-packages], such as [django-autocomplete-light][django-autocomplete-light], that you may want to refer to. Note that you will not be able to simply include these components as standard widgets, but will need to write the HTML template explicitly. This is because REST framework 3.0 no longer supports the `widget` keyword argument since it now uses templated HTML generation. -*Screenshot of the autocomplete-light widget* +Better support for autocomplete inputs is planned in future versions. --- @@ -175,4 +165,3 @@ You can now add the `autocomplete_light.ChoiceWidget` widget to the serializer f [autocomplete-packages]: https://www.djangopackages.com/grids/g/auto-complete/ [django-autocomplete-light]: https://github.com/yourlabs/django-autocomplete-light [django-autocomplete-light-install]: http://django-autocomplete-light.readthedocs.org/en/latest/#install -[autocomplete-image]: ../img/autocomplete.png 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 |
