aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/api-guide/fields.md179
-rw-r--r--docs/api-guide/generic-views.md14
-rw-r--r--docs/api-guide/relations.md139
-rw-r--r--docs/api-guide/serializers.md20
-rw-r--r--docs/index.md14
-rw-r--r--docs/template.html1
-rw-r--r--docs/topics/credits.md8
-rw-r--r--docs/topics/release-notes.md56
8 files changed, 259 insertions, 172 deletions
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index 50a09701..5bc8f7f7 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -2,11 +2,11 @@
# Serializer fields
-> Flat is better than nested.
+> Each field in a Form class is responsible not only for validating data, but also for "cleaning" it -- normalizing it to a consistent format.
>
-> — [The Zen of Python][cite]
+> — [Django documentation][cite]
-Serializer fields handle converting between primative values and internal datatypes. They also deal with validating input values, as well as retrieving and setting the values from their parent objects.
+Serializer fields handle converting between primitive values and internal datatypes. They also deal with validating input values, as well as retrieving and setting the values from their parent objects.
---
@@ -28,7 +28,7 @@ Defaults to the name of the field.
### `read_only`
-Set this to `True` to ensure that the field is used when serializing a representation, but is not used when updating an instance dureing deserialization.
+Set this to `True` to ensure that the field is used when serializing a representation, but is not used when updating an instance during deserialization.
Defaults to `False`
@@ -41,7 +41,7 @@ Defaults to `True`.
### `default`
-If set, this gives the default value that will be used for the field if none is supplied. If not set the default behaviour is to not populate the attribute at all.
+If set, this gives the default value that will be used for the field if none is supplied. If not set the default behavior is to not populate the attribute at all.
### `validators`
@@ -96,9 +96,9 @@ Would produce output similar to:
'expired': True
}
-By default, the `Field` class will perform a basic translation of the source value into primative datatypes, falling back to unicode representations of complex datatypes when necessary.
+By default, the `Field` class will perform a basic translation of the source value into primitive datatypes, falling back to unicode representations of complex datatypes when necessary.
-You can customize this behaviour by overriding the `.to_native(self, value)` method.
+You can customize this behavior by overriding the `.to_native(self, value)` method.
## WritableField
@@ -110,6 +110,24 @@ A generic field that can be tied to any arbitrary model field. The `ModelField`
**Signature:** `ModelField(model_field=<Django ModelField class>)`
+## SerializerMethodField
+
+This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object. The field's constructor accepts a single argument, which is the name of the method on the serializer to be called. The method should accept a single argument (in addition to `self`), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:
+
+ from rest_framework import serializers
+ from django.contrib.auth.models import User
+ from django.utils.timezone import now
+
+ class UserSerializer(serializers.ModelSerializer):
+
+ days_since_joined = serializers.SerializerMethodField('get_days_since_joined')
+
+ class Meta:
+ model = User
+
+ def get_days_since_joined(self, obj):
+ return (now() - obj.date_joined).days
+
---
# Typed Fields
@@ -211,151 +229,8 @@ Signature and validation is the same as with `FileField`.
---
-**Note:** `FileFields` and `ImageFields` are only suitable for use with MultiPartParser, since eg json doesn't support file uploads.
+**Note:** `FileFields` and `ImageFields` are only suitable for use with MultiPartParser, since e.g. json doesn't support file uploads.
Django's regular [FILE_UPLOAD_HANDLERS] are used for handling uploaded files.
----
-
-# Relational Fields
-
-Relational fields are used to represent model relationships. They can be applied to `ForeignKey`, `ManyToManyField` and `OneToOneField` relationships, as well as to reverse relationships, and custom relationships such as `GenericForeignKey`.
-
-## RelatedField
-
-This field can be applied to any of the following:
-
-* A `ForeignKey` field.
-* A `OneToOneField` field.
-* A reverse OneToOne relationship
-* Any other "to-one" relationship.
-
-By default `RelatedField` will represent the target of the field using it's `__unicode__` method.
-
-You can customise this behaviour by subclassing `ManyRelatedField`, and overriding the `.to_native(self, value)` method.
-
-## ManyRelatedField
-
-This field can be applied to any of the following:
-
-* A `ManyToManyField` field.
-* A reverse ManyToMany relationship.
-* A reverse ForeignKey relationship
-* Any other "to-many" relationship.
-
-By default `ManyRelatedField` will represent the targets of the field using their `__unicode__` method.
-
-For example, given the following models:
-
- class TaggedItem(models.Model):
- """
- Tags arbitrary model instances using a generic relation.
-
- See: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/
- """
- tag = models.SlugField()
- content_type = models.ForeignKey(ContentType)
- object_id = models.PositiveIntegerField()
- content_object = GenericForeignKey('content_type', 'object_id')
-
- def __unicode__(self):
- return self.tag
-
-
- class Bookmark(models.Model):
- """
- A bookmark consists of a URL, and 0 or more descriptive tags.
- """
- url = models.URLField()
- tags = GenericRelation(TaggedItem)
-
-And a model serializer defined like this:
-
- class BookmarkSerializer(serializers.ModelSerializer):
- tags = serializers.ManyRelatedField(source='tags')
-
- class Meta:
- model = Bookmark
- exclude = ('id',)
-
-Then an example output format for a Bookmark instance would be:
-
- {
- 'tags': [u'django', u'python'],
- 'url': u'https://www.djangoproject.com/'
- }
-
-## PrimaryKeyRelatedField / ManyPrimaryKeyRelatedField
-
-`PrimaryKeyRelatedField` and `ManyPrimaryKeyRelatedField` will represent the target of the relationship using it's primary key.
-
-By default these fields are read-write, although you can change this behaviour using the `read_only` flag.
-
-**Arguments**:
-
-* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
-* `null` - If set to `True`, the field will accept values of `None` or the emptystring for nullable relationships.
-
-## SlugRelatedField / ManySlugRelatedField
-
-`SlugRelatedField` and `ManySlugRelatedField` will represent the target of the relationship using a unique slug.
-
-By default these fields read-write, although you can change this behaviour using the `read_only` flag.
-
-**Arguments**:
-
-* `slug_field` - The field on the target that should be used to represent it. This should be a field that uniquely identifies any given instance. For example, `username`.
-* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
-* `null` - If set to `True`, the field will accept values of `None` or the emptystring for nullable relationships.
-
-## HyperlinkedRelatedField / ManyHyperlinkedRelatedField
-
-`HyperlinkedRelatedField` and `ManyHyperlinkedRelatedField` will represent the target of the relationship using a hyperlink.
-
-By default, `HyperlinkedRelatedField` is read-write, although you can change this behaviour using the `read_only` flag.
-
-**Arguments**:
-
-* `view_name` - The view name that should be used as the target of the relationship. **required**.
-* `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
-* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
-* `slug_field` - The field on the target that should be used for the lookup. Default is `'slug'`.
-* `pk_url_kwarg` - The named url parameter for the pk field lookup. Default is `pk`.
-* `slug_url_kwarg` - The named url parameter for the slug field lookup. Default is to use the same value as given for `slug_field`.
-* `null` - If set to `True`, the field will accept values of `None` or the emptystring for nullable relationships.
-
-## HyperLinkedIdentityField
-
-This field can be applied as an identity relationship, such as the `'url'` field on a HyperlinkedModelSerializer.
-
-This field is always read-only.
-
-**Arguments**:
-
-* `view_name` - The view name that should be used as the target of the relationship. **required**.
-* `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
-* `slug_field` - The field on the target that should be used for the lookup. Default is `'slug'`.
-* `pk_url_kwarg` - The named url parameter for the pk field lookup. Default is `pk`.
-* `slug_url_kwarg` - The named url parameter for the slug field lookup. Default is to use the same value as given for `slug_field`.
-
-# Other Fields
-
-## SerializerMethodField
-
-This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object. The field's constructor accepts a single argument, which is the name of the method on the serializer to be called. The method should accept a single argument (in addition to `self`), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:
-
- from rest_framework import serializers
- from django.contrib.auth.models import User
- from django.utils.timezone import now
-
- class UserSerializer(serializers.ModelSerializer):
-
- days_since_joined = serializers.SerializerMethodField('get_days_since_joined')
-
- class Meta:
- model = User
-
- def get_days_since_joined(self, obj):
- return (now() - obj.date_joined).days
-
-[cite]: http://www.python.org/dev/peps/pep-0020/
+[cite]: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.cleaned_data
[FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index 27c7d3f6..693e210d 100644
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -85,7 +85,7 @@ Extends: [SingleObjectAPIView], [DestroyModelMixin]
Used for **update-only** endpoints for a **single model instance**.
-Provides a `put` method handler.
+Provides `put` and `patch` method handlers.
Extends: [SingleObjectAPIView], [UpdateModelMixin]
@@ -97,6 +97,14 @@ Provides `get` and `post` method handlers.
Extends: [MultipleObjectAPIView], [ListModelMixin], [CreateModelMixin]
+## RetrieveUpdateAPIView
+
+Used for **read or update** endpoints to represent a **single model instance**.
+
+Provides `get`, `put` and `patch` method handlers.
+
+Extends: [SingleObjectAPIView], [RetrieveModelMixin], [UpdateModelMixin]
+
## RetrieveDestroyAPIView
Used for **read or delete** endpoints to represent a **single model instance**.
@@ -109,7 +117,7 @@ Extends: [SingleObjectAPIView], [RetrieveModelMixin], [DestroyModelMixin]
Used for **read-write-delete** endpoints to represent a **single model instance**.
-Provides `get`, `put` and `delete` method handlers.
+Provides `get`, `put`, `patch` and `delete` method handlers.
Extends: [SingleObjectAPIView], [RetrieveModelMixin], [UpdateModelMixin], [DestroyModelMixin]
@@ -197,6 +205,8 @@ If an object is created, for example when making a `DELETE` request followed by
If the request data provided for updating the object was invalid, a `400 Bad Request` response will be returned, with the error details as the body of the response.
+A boolean `partial` keyword argument may be supplied to the `.update()` method. If `partial` is set to `True`, all fields for the update will be optional. This allows support for HTTP `PATCH` requests.
+
Should be mixed in with [SingleObjectAPIView].
## DestroyModelMixin
diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md
new file mode 100644
index 00000000..351b5e09
--- /dev/null
+++ b/docs/api-guide/relations.md
@@ -0,0 +1,139 @@
+<a class="github" href="relations.py"></a>
+
+# Serializer relations
+
+> Bad programmers worry about the code.
+> Good programmers worry about data structures and their relationships.
+>
+> &mdash; [Linus Torvalds][cite]
+
+
+Relational fields are used to represent model relationships. They can be applied to `ForeignKey`, `ManyToManyField` and `OneToOneField` relationships, as well as to reverse relationships, and custom relationships such as `GenericForeignKey`.
+
+---
+
+**Note:** The relational fields are declared in `relations.py`, but by convention you should import them using `from rest_framework import serializers` and refer to fields as `serializers.<FieldName>`.
+
+---
+
+## RelatedField
+
+This field can be applied to any of the following:
+
+* A `ForeignKey` field.
+* A `OneToOneField` field.
+* A reverse OneToOne relationship
+* Any other "to-one" relationship.
+
+By default `RelatedField` will represent the target of the field using it's `__unicode__` method.
+
+You can customize this behavior by subclassing `ManyRelatedField`, and overriding the `.to_native(self, value)` method.
+
+## ManyRelatedField
+
+This field can be applied to any of the following:
+
+* A `ManyToManyField` field.
+* A reverse ManyToMany relationship.
+* A reverse ForeignKey relationship
+* Any other "to-many" relationship.
+
+By default `ManyRelatedField` will represent the targets of the field using their `__unicode__` method.
+
+For example, given the following models:
+
+ class TaggedItem(models.Model):
+ """
+ Tags arbitrary model instances using a generic relation.
+
+ See: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/
+ """
+ tag = models.SlugField()
+ content_type = models.ForeignKey(ContentType)
+ object_id = models.PositiveIntegerField()
+ content_object = GenericForeignKey('content_type', 'object_id')
+
+ def __unicode__(self):
+ return self.tag
+
+
+ class Bookmark(models.Model):
+ """
+ A bookmark consists of a URL, and 0 or more descriptive tags.
+ """
+ url = models.URLField()
+ tags = GenericRelation(TaggedItem)
+
+And a model serializer defined like this:
+
+ class BookmarkSerializer(serializers.ModelSerializer):
+ tags = serializers.ManyRelatedField(source='tags')
+
+ class Meta:
+ model = Bookmark
+ exclude = ('id',)
+
+Then an example output format for a Bookmark instance would be:
+
+ {
+ 'tags': [u'django', u'python'],
+ 'url': u'https://www.djangoproject.com/'
+ }
+
+## PrimaryKeyRelatedField
+## ManyPrimaryKeyRelatedField
+
+`PrimaryKeyRelatedField` and `ManyPrimaryKeyRelatedField` will represent the target of the relationship using it's primary key.
+
+By default these fields are read-write, although you can change this behavior using the `read_only` flag.
+
+**Arguments**:
+
+* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
+* `null` - If set to `True`, the field will accept values of `None` or the empty-string for nullable relationships.
+
+## SlugRelatedField
+## ManySlugRelatedField
+
+`SlugRelatedField` and `ManySlugRelatedField` will represent the target of the relationship using a unique slug.
+
+By default these fields read-write, although you can change this behavior using the `read_only` flag.
+
+**Arguments**:
+
+* `slug_field` - The field on the target that should be used to represent it. This should be a field that uniquely identifies any given instance. For example, `username`.
+* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
+* `null` - If set to `True`, the field will accept values of `None` or the empty-string for nullable relationships.
+
+## HyperlinkedRelatedField
+## ManyHyperlinkedRelatedField
+
+`HyperlinkedRelatedField` and `ManyHyperlinkedRelatedField` will represent the target of the relationship using a hyperlink.
+
+By default, `HyperlinkedRelatedField` is read-write, although you can change this behavior using the `read_only` flag.
+
+**Arguments**:
+
+* `view_name` - The view name that should be used as the target of the relationship. **required**.
+* `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
+* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
+* `slug_field` - The field on the target that should be used for the lookup. Default is `'slug'`.
+* `pk_url_kwarg` - The named url parameter for the pk field lookup. Default is `pk`.
+* `slug_url_kwarg` - The named url parameter for the slug field lookup. Default is to use the same value as given for `slug_field`.
+* `null` - If set to `True`, the field will accept values of `None` or the empty-string for nullable relationships.
+
+## HyperLinkedIdentityField
+
+This field can be applied as an identity relationship, such as the `'url'` field on a HyperlinkedModelSerializer.
+
+This field is always read-only.
+
+**Arguments**:
+
+* `view_name` - The view name that should be used as the target of the relationship. **required**.
+* `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
+* `slug_field` - The field on the target that should be used for the lookup. Default is `'slug'`.
+* `pk_url_kwarg` - The named url parameter for the pk field lookup. Default is `pk`.
+* `slug_url_kwarg` - The named url parameter for the slug field lookup. Default is to use the same value as given for `slug_field`.
+
+[cite]: http://lwn.net/Articles/193245/
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index 19efde3c..d98a602f 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -4,8 +4,7 @@
> Expanding the usefulness of the serializers is something that we would
like to address. However, it's not a trivial problem, and it
-will take some serious design work. Any offers to help out in this
-area would be gratefully accepted.
+will take some serious design work.
>
> &mdash; Russell Keith-Magee, [Django users group][cite]
@@ -110,7 +109,22 @@ Your `validate_<fieldname>` methods should either just return the `attrs` dictio
### 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`.
+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`. For example:
+
+ from rest_framework import serializers
+
+ class EventSerializer(serializers.Serializer):
+ description = serializers.CahrField(max_length=100)
+ start = serializers.DateTimeField()
+ finish = serializers.DateTimeField()
+
+ def validate(self, attrs):
+ """
+ Check that the start is before the stop.
+ """
+ if attrs['start'] < attrs['finish']:
+ raise serializers.ValidationError("finish must occur after start")
+ return attrs
## Saving object state
diff --git a/docs/index.md b/docs/index.md
index cc0f2a13..080eca6f 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -15,7 +15,7 @@ Django REST framework is a lightweight library that makes it easy to build Web A
Web APIs built using REST framework are fully self-describing and web browseable - a huge useability win for your developers. It also supports a wide range of media types, authentication and permission policies out of the box.
-If you are considering using REST framework for your API, we recommend reading the [REST framework 2 announcment][rest-framework-2-announcement] which gives a good overview of the framework and it's capabilities.
+If you are considering using REST framework for your API, we recommend reading the [REST framework 2 announcement][rest-framework-2-announcement] which gives a good overview of the framework and it's capabilities.
There is also a sandbox API you can use for testing purposes, [available here][sandbox].
@@ -52,21 +52,21 @@ Install using `pip`, including any optional packages you want...
pip install -r requirements.txt
pip install -r optionals.txt
-Add `rest_framework` to your `INSTALLED_APPS`.
+Add `'rest_framework'` to your `INSTALLED_APPS` setting.
INSTALLED_APPS = (
...
'rest_framework',
)
-If you're intending to use the browseable API you'll want to add REST framework's login and logout views. Add the following to your root `urls.py` file.
+If you're intending to use the browseable API you'll probably also want to add REST framework's login and logout views. Add the following to your root `urls.py` file.
urlpatterns = patterns('',
...
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)
-Note that the URL path can be whatever you want, but you must include `rest_framework.urls` with the `rest_framework` namespace.
+Note that the URL path can be whatever you want, but you must include `'rest_framework.urls'` with the `'rest_framework'` namespace.
## Quickstart
@@ -94,6 +94,7 @@ The API guide is your complete reference manual to all the functionality provide
* [Renderers][renderers]
* [Serializers][serializers]
* [Serializer fields][fields]
+* [Serializer relations][relations]
* [Authentication][authentication]
* [Permissions][permissions]
* [Throttling][throttling]
@@ -137,7 +138,7 @@ Paid support is also available from [DabApps], and can include work on REST fram
## License
-Copyright (c) 2011-2012, Tom Christie
+Copyright (c) 2011-2013, Tom Christie
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -161,7 +162,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[travis]: http://travis-ci.org/tomchristie/django-rest-framework?branch=master
-[travis-build-image]: https://secure.travis-ci.org/tomchristie/django-rest-framework.png?branch=restframework2
+[travis-build-image]: https://secure.travis-ci.org/tomchristie/django-rest-framework.png?branch=master
[urlobject]: https://github.com/zacharyvoase/urlobject
[markdown]: http://pypi.python.org/pypi/Markdown/
[yaml]: http://pypi.python.org/pypi/PyYAML
@@ -185,6 +186,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[renderers]: api-guide/renderers.md
[serializers]: api-guide/serializers.md
[fields]: api-guide/fields.md
+[relations]: api-guide/relations.md
[authentication]: api-guide/authentication.md
[permissions]: api-guide/permissions.md
[throttling]: api-guide/throttling.md
diff --git a/docs/template.html b/docs/template.html
index 676a4807..d789cc58 100644
--- a/docs/template.html
+++ b/docs/template.html
@@ -72,6 +72,7 @@
<li><a href="{{ base_url }}/api-guide/renderers{{ suffix }}">Renderers</a></li>
<li><a href="{{ base_url }}/api-guide/serializers{{ suffix }}">Serializers</a></li>
<li><a href="{{ base_url }}/api-guide/fields{{ suffix }}">Serializer fields</a></li>
+ <li><a href="{{ base_url }}/api-guide/relations{{ suffix }}">Serializer relations</a></li>
<li><a href="{{ base_url }}/api-guide/authentication{{ suffix }}">Authentication</a></li>
<li><a href="{{ base_url }}/api-guide/permissions{{ suffix }}">Permissions</a></li>
<li><a href="{{ base_url }}/api-guide/throttling{{ suffix }}">Throttling</a></li>
diff --git a/docs/topics/credits.md b/docs/topics/credits.md
index 8b8cac1a..008e4a1b 100644
--- a/docs/topics/credits.md
+++ b/docs/topics/credits.md
@@ -81,6 +81,10 @@ The following people have helped make REST framework great.
* Szymon Teżewski - [sunscrapers]
* Joel Marcotte - [joual]
* Trey Hunner - [treyhunner]
+* Roman Akinfold - [akinfold]
+* Toran Billups - [toranb]
+* Sébastien Béal - [sebastibe]
+* Andrew Hankinson - [ahankinson]
Many thanks to everyone who's contributed to the project.
@@ -197,3 +201,7 @@ You can also contact [@_tomchristie][twitter] directly on twitter.
[sunscrapers]: https://github.com/sunscrapers
[joual]: https://github.com/joual
[treyhunner]: https://github.com/treyhunner
+[akinfold]: https://github.com/akinfold
+[toranb]: https://github.com/toranb
+[sebastibe]: https://github.com/sebastibe
+[ahankinson]: https://github.com/ahankinson
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 71fa3c03..6230d39e 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -4,10 +4,46 @@
>
> &mdash; Eric S. Raymond, [The Cathedral and the Bazaar][cite].
+## Versioning
+
+Minor version numbers (0.0.x) are used for changes that are API compatible. You should be able to upgrade between minor point releases without any other code changes.
+
+Medium version numbers (0.x.0) may include minor API changes. You should read the release notes carefully before upgrading between medium point releases.
+
+Major version numbers (x.0.0) are reserved for project milestones. No major point releases are currently planned.
+
+---
+
## 2.1.x series
### Master
+* Added `PATCH` support.
+* Added `RetrieveUpdateAPIView`.
+* Relation changes are now persisted in `save` instead of in `.restore_object`.
+* Cleanup unused internal `save_m2m` flag on `ModelSerializer.save()`.
+* Tweak behavior of hyperlinked fields with an explicit format suffix.
+* Relation changes are now persisted in `.save()` instead of in `.restore_object()`.
+* Bugfix: Fix issue with FileField validation with files=None.
+
+### 2.1.14
+
+**Date**: 31st Dec 2012
+
+* Bugfix: ModelSerializers now include reverse FK fields on creation.
+* Bugfix: Model fields with `blank=True` are now `required=False` by default.
+* Bugfix: Nested serializers now support nullable relationships.
+
+**Note**: From 2.1.14 onwards, relational fields move out of the `fields.py` module and into the new `relations.py` module, in order to seperate them from regular data type fields, such as `CharField` and `IntegerField`.
+
+This change will not affect user code, so long as it's following the recommended import style of `from rest_framework import serializers` and refering to fields using the style `serializers.PrimaryKeyRelatedField`.
+
+
+### 2.1.13
+
+**Date**: 28th Dec 2012
+
+* Support configurable `STATICFILES_STORAGE` storage.
* Bugfix: Related fields now respect the required flag, and may be required=False.
### 2.1.12
@@ -105,7 +141,7 @@
* Support use of HTML exception templates. Eg. `403.html`
* Hyperlinked fields take optional `slug_field`, `slug_url_kwarg` and `pk_url_kwarg` arguments.
-* Bugfix: Deal with optional trailing slashs properly when generating breadcrumbs.
+* Bugfix: Deal with optional trailing slashes properly when generating breadcrumbs.
* Bugfix: Make textareas same width as other fields in browsable API.
* Private API change: `.get_serializer` now uses same `instance` and `data` ordering as serializer initialization.
@@ -113,8 +149,6 @@
**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.**
* `queryset` argument is now optional on writable model fields.
* Hyperlinked related fields optionally take `slug_field` and `slug_url_kwarg` arguments.
@@ -123,6 +157,8 @@
* Bugfix: Support choice field in Browseable API.
* Bugfix: Related fields with `read_only=True` do not require a `queryset` argument.
+**API-incompatible changes**: Please read [this thread][2.1.0-notes] regarding the `instance` and `data` keyword args before updating to 2.1.0.
+
---
## 2.0.x series
@@ -159,9 +195,9 @@
* Allow views to specify template used by TemplateRenderer
* More consistent error responses
* Some serializer fixes
-* Fix internet explorer ajax behaviour
+* Fix internet explorer ajax behavior
* Minor xml and yaml fixes
-* Improve setup (eg use staticfiles, not the defunct ADMIN_MEDIA_PREFIX)
+* Improve setup (e.g. use staticfiles, not the defunct ADMIN_MEDIA_PREFIX)
* Sensible absolute URL generation, not using hacky set_script_prefix
---
@@ -172,13 +208,13 @@
* Added DjangoModelPermissions class to support `django.contrib.auth` style permissions.
* Use `staticfiles` for css files.
- - Easier to override. Won't conflict with customised admin styles (eg grappelli)
+ - 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. Explict is better than implicit.
-* Saner template variable autoescaping.
-* Tider setup.py
+ - 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.
@@ -266,5 +302,7 @@
* Initial release.
[cite]: http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s04.html
+[staticfiles14]: https://docs.djangoproject.com/en/1.4/howto/static-files/#with-a-template-tag
+[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