diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/api-guide/fields.md | 179 | ||||
| -rw-r--r-- | docs/api-guide/generic-views.md | 20 | ||||
| -rw-r--r-- | docs/api-guide/relations.md | 139 | ||||
| -rw-r--r-- | docs/api-guide/serializers.md | 20 | ||||
| -rw-r--r-- | docs/index.md | 10 | ||||
| -rw-r--r-- | docs/template.html | 1 | ||||
| -rw-r--r-- | docs/topics/credits.md | 20 | ||||
| -rw-r--r-- | docs/topics/release-notes.md | 145 | ||||
| -rw-r--r-- | docs/tutorial/5-relationships-and-hyperlinked-apis.md | 4 |
9 files changed, 330 insertions, 208 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 ef09dfe5..693e210d 100644 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -7,11 +7,11 @@ > > — [Django Documentation][cite] -One of the key benefits of class based views is the way they allow you to compose bits of reusable behaviour. REST framework takes advantage of this by providing a number of pre-built views that provide for commonly used patterns. +One of the key benefits of class based views is the way they allow you to compose bits of reusable behaviour. REST framework takes advantage of this by providing a number of pre-built views that provide for commonly used patterns. The generic views provided by REST framework allow you to quickly build API views that map closely to your database models. -If the generic views don't suit the needs of your API, you can drop down to using the regular `APIView` class, or reuse the mixins and base classes used by the generic views to compose your own set of reusable generic views. +If the generic views don't suit the needs of your API, you can drop down to using the regular `APIView` class, or reuse the mixins and base classes used by the generic views to compose your own set of reusable generic views. ## Examples @@ -29,7 +29,7 @@ For more complex cases you might also want to override various methods on the vi model = User serializer_class = UserSerializer permission_classes = (IsAdminUser,) - + def get_paginate_by(self, queryset): """ Use smaller pagination for HTML representations. @@ -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] @@ -101,7 +101,7 @@ Extends: [MultipleObjectAPIView], [ListModelMixin], [CreateModelMixin] Used for **read or update** endpoints to represent a **single model instance**. -Provides `get` and `put` method handlers. +Provides `get`, `put` and `patch` method handlers. Extends: [SingleObjectAPIView], [RetrieveModelMixin], [UpdateModelMixin] @@ -117,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] @@ -158,14 +158,14 @@ Provides a base view for acting on a single object, by combining REST framework' * `queryset` - The queryset that should be used when retrieving an object from this view. If unset, defaults to the default queryset manager for `self.model`. * `pk_kwarg` - The URL kwarg that should be used to look up objects by primary key. Defaults to `'pk'`. [Can only be set to non-default on Django 1.4+] -* `slug_kwarg` - The URL kwarg that should be used to look up objects by a slug. Defaults to `'slug'`. [Can only be set to non-default on Django 1.4+] +* `slug_url_kwarg` - The URL kwarg that should be used to look up objects by a slug. Defaults to `'slug'`. [Can only be set to non-default on Django 1.4+] * `slug_field` - The field on the model that should be used to look up objects by a slug. If used, this should typically be set to a field with `unique=True`. Defaults to `'slug'`. --- # Mixins -The mixin classes provide the actions that are used to provide the basic view behaviour. Note that the mixin classes provide action methods rather than defining the handler methods such as `.get()` and `.post()` directly. This allows for more flexible composition of behaviour. +The mixin classes provide the actions that are used to provide the basic view behaviour. Note that the mixin classes provide action methods rather than defining the handler methods such as `.get()` and `.post()` directly. This allows for more flexible composition of behaviour. ## ListModelMixin @@ -205,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 @@ -228,4 +230,4 @@ Should be mixed in with [SingleObjectAPIView]. [CreateModelMixin]: #createmodelmixin [RetrieveModelMixin]: #retrievemodelmixin [UpdateModelMixin]: #updatemodelmixin -[DestroyModelMixin]: #destroymodelmixin
\ No newline at end of file +[DestroyModelMixin]: #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. +> +> — [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. > > — 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..4d50e5d6 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] @@ -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 cdf57f7e..c4277a23 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -77,6 +77,13 @@ The following people have helped make REST framework great. * Venkata Subramanian Mahalingam - [annacoder] * George Kappel - [gkappel] * Colin Murtaugh - [cmurtaugh] +* Simon Pantzare - [pilt] +* Szymon Teżewski - [sunscrapers] +* Joel Marcotte - [joual] +* Trey Hunner - [treyhunner] +* Roman Akinfold - [akinfold] +* Toran Billups - [toranb] +* Sébastien Béal - [sebastibe] Many thanks to everyone who's contributed to the project. @@ -96,10 +103,9 @@ Development of REST framework 2.0 was sponsored by [DabApps]. ## Contact -To contact the author directly: +For usage questions please see the [REST framework discussion group][group]. -* twitter: [@_tomchristie][twitter] -* email: [tom@tomchristie.com][email] +You can also contact [@_tomchristie][twitter] directly on twitter. [email]: mailto:tom@tomchristie.com [twitter]: http://twitter.com/_tomchristie @@ -113,6 +119,7 @@ To contact the author directly: [dabapps]: http://lab.dabapps.com [sandbox]: http://restframework.herokuapp.com/ [heroku]: http://www.heroku.com/ +[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework [tomchristie]: https://github.com/tomchristie [markotibold]: https://github.com/markotibold @@ -189,3 +196,10 @@ To contact the author directly: [annacoder]: https://github.com/annacoder [gkappel]: https://github.com/gkappel [cmurtaugh]: https://github.com/cmurtaugh +[pilt]: https://github.com/pilt +[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 diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index a74ee520..e4bd1217 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -4,9 +4,64 @@ > > — Eric S. Raymond, [The Cathedral and the Bazaar][cite]. -## Master +## Versioning -* Added `RetrieveUpdateAPIView` +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`. + +### 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 + +**Date**: 21st Dec 2012 + +* Bugfix: Fix bug that could occur using ChoiceField. +* Bugfix: Fix exception in browseable API on DELETE. +* Bugfix: Fix issue where pk was was being set to a string if set by URL kwarg. + +### 2.1.11 + +**Date**: 17th Dec 2012 + +* Bugfix: Fix issue with M2M fields in browseable API. + +### 2.1.10 + +**Date**: 17th Dec 2012 + +* Bugfix: Ensure read-only fields don't have model validation applied. +* Bugfix: Fix hyperlinked fields in paginated results. ## 2.1.9 @@ -16,14 +71,14 @@ * Bugfix: Fix `Meta.fields` only working as tuple not as list. * Bugfix: Edge case if unnecessarily specifying `required=False` on read only field. -## 2.1.8 +### 2.1.8 **Date**: 8th Dec 2012 * Fix for creating nullable Foreign Keys with `''` as well as `None`. * Added `null=<bool>` related field option. -## 2.1.7 +### 2.1.7 **Date**: 7th Dec 2012 @@ -35,19 +90,19 @@ * Make `Request.user` settable. * Bugfix: Fix `RegexField` to work with `BrowsableAPIRenderer`. -## 2.1.6 +### 2.1.6 **Date**: 23rd Nov 2012 * Bugfix: Unfix DjangoModelPermissions. (I am a doofus.) -## 2.1.5 +### 2.1.5 **Date**: 23rd Nov 2012 * Bugfix: Fix DjangoModelPermissions. -## 2.1.4 +### 2.1.4 **Date**: 22nd Nov 2012 @@ -58,7 +113,7 @@ * Added `obtain_token_view` to get tokens when using `TokenAuthentication`. * Bugfix: Django 1.5 configurable user support for `TokenAuthentication`. -## 2.1.3 +### 2.1.3 **Date**: 16th Nov 2012 @@ -69,29 +124,27 @@ * 201 Responses now return a 'Location' header. * Bugfix: Serializer fields now respect `max_length`. -## 2.1.2 +### 2.1.2 **Date**: 9th Nov 2012 * **Filtering support.** * Bugfix: Support creation of objects with reverse M2M relations. -## 2.1.1 +### 2.1.1 **Date**: 7th Nov 2012 * 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. -## 2.1.0 +### 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.** * `queryset` argument is now optional on writable model fields. * Hyperlinked related fields optionally take `slug_field` and `slug_url_kwarg` arguments. @@ -100,13 +153,19 @@ * Bugfix: Support choice field in Browseable API. * Bugfix: Related fields with `read_only=True` do not require a `queryset` argument. -## 2.0.2 +**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 + +### 2.0.2 **Date**: 2nd Nov 2012 * Fix issues with pk related fields in the browsable API. -## 2.0.1 +### 2.0.1 **Date**: 1st Nov 2012 @@ -114,7 +173,7 @@ * Added SlugRelatedField and ManySlugRelatedField. * If PUT creates an instance return '201 Created', instead of '200 OK'. -## 2.0.0 +### 2.0.0 **Date**: 30th Oct 2012 @@ -123,34 +182,40 @@ --- -## 0.4.0 +## 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 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 -## 0.3.3 +--- + +## 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 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. -## 0.3.2 +### 0.3.2 * Bugfixes: * Fix 403 for POST and PUT from the UI with UserLoggedInAuthentication (#115) @@ -162,37 +227,41 @@ * 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 +### 0.3.1 * [not documented] -## 0.3.0 +### 0.3.0 * JSONP Support * Bugfixes, including support for latest markdown release -## 0.2.4 +--- + +## 0.2.x series + +### 0.2.4 * Fix broken IsAdminUser permission. * OPTIONS support. * XMLParser. * Drop mentions of Blog, BitBucket. -## 0.2.3 +### 0.2.3 * Fix some throttling bugs. * ``X-Throttle`` header on throttling. * Support for nesting resources on related models. -## 0.2.2 +### 0.2.2 * Throttling support complete. -## 0.2.1 +### 0.2.1 * Couple of simple bugfixes over 0.2.0 -## 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. @@ -216,14 +285,20 @@ * 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.1 +--- + +## 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 +### 0.1.0 * 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 diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index b5d37875..216ca433 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -163,9 +163,9 @@ You can review the final [tutorial code][repo] on GitHub, or try out a live exam We've reached the end of our tutorial. If you want to get more involved in the REST framework project, here's a few places you can start: -* Contribute on [GitHub][github] by reviewing and subitting issues, and making pull requests. +* Contribute on [GitHub][github] by reviewing and submitting issues, and making pull requests. * Join the [REST framework discussion group][group], and help build the community. -* Follow the author [on Twitter][twitter] and say hi. +* [Follow the author on Twitter][twitter] and say hi. **Now go build awesome things.** |
