aboutsummaryrefslogtreecommitdiffstats
path: root/docs/topics
diff options
context:
space:
mode:
authorCarlton Gibson2014-12-01 11:22:39 +0100
committerCarlton Gibson2014-12-01 11:22:39 +0100
commitef26f43de4a0c9ac3081c06a383b5d3d4d007797 (patch)
treebf6abcd15f0e58f4fa79a83cd4e051b8987dd311 /docs/topics
parentc50a42bddc66e28d624cd3caadd2d63502ac2e6e (diff)
parent72c4ec4e189796e506655e275cd9c77abe98e1b9 (diff)
downloaddjango-rest-framework-ef26f43de4a0c9ac3081c06a383b5d3d4d007797.tar.bz2
Merge branch 'master' of github.com:tomchristie/django-rest-framework
Diffstat (limited to 'docs/topics')
-rw-r--r--docs/topics/2.2-announcement.md8
-rw-r--r--docs/topics/2.3-announcement.md8
-rw-r--r--docs/topics/3.0-announcement.md150
-rw-r--r--docs/topics/browsable-api.md33
-rw-r--r--docs/topics/contributing.md31
-rw-r--r--docs/topics/documenting-your-api.md8
-rw-r--r--docs/topics/kickstarter-announcement.md144
-rw-r--r--docs/topics/release-notes.md124
-rw-r--r--docs/topics/rest-framework-2-announcement.md4
-rw-r--r--docs/topics/rest-hypermedia-hateoas.md8
-rw-r--r--docs/topics/third-party-resources.md332
-rw-r--r--docs/topics/writable-nested-serializers.md10
12 files changed, 514 insertions, 346 deletions
diff --git a/docs/topics/2.2-announcement.md b/docs/topics/2.2-announcement.md
index a997c782..1df52cff 100644
--- a/docs/topics/2.2-announcement.md
+++ b/docs/topics/2.2-announcement.md
@@ -42,7 +42,7 @@ The 2.2 release makes a few changes to the API, in order to make it more consist
The `ManyRelatedField()` style is being deprecated in favor of a new `RelatedField(many=True)` syntax.
-For example, if a user is associated with multiple questions, which we want to represent using a primary key relationship, we might use something like the following:
+For example, if a user is associated with multiple questions, which we want to represent using a primary key relationship, we might use something like the following:
class UserSerializer(serializers.HyperlinkedModelSerializer):
questions = serializers.PrimaryKeyRelatedField(many=True)
@@ -58,10 +58,10 @@ The change also applies to serializers. If you have a nested serializer, you sh
class Meta:
model = Track
fields = ('name', 'duration')
-
+
class AlbumSerializer(serializer.ModelSerializer):
tracks = TrackSerializer(many=True)
-
+
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
@@ -87,7 +87,7 @@ For example, is a user account has an optional foreign key to a company, that yo
This is in line both with the rest of the serializer fields API, and with Django's `Form` and `ModelForm` API.
-Using `required` throughout the serializers API means you won't need to consider if a particular field should take `blank` or `null` arguments instead of `required`, and also means there will be more consistent behavior for how fields are treated when they are not present in the incoming data.
+Using `required` throughout the serializers API means you won't need to consider if a particular field should take `blank` or `null` arguments instead of `required`, and also means there will be more consistent behavior for how fields are treated when they are not present in the incoming data.
The `null=True` argument will continue to function, and will imply `required=False`, but will raise a `PendingDeprecationWarning`.
diff --git a/docs/topics/2.3-announcement.md b/docs/topics/2.3-announcement.md
index 7c800afa..9c9f3e9f 100644
--- a/docs/topics/2.3-announcement.md
+++ b/docs/topics/2.3-announcement.md
@@ -27,7 +27,7 @@ As an example of just how simple REST framework APIs can now be, here's an API w
class GroupViewSet(viewsets.ModelViewSet):
model = Group
-
+
# Routers provide an easy way of automatically determining the URL conf
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
@@ -197,13 +197,13 @@ Usage of the old-style attributes continues to be supported, but will raise a `P
For most cases APIs using model fields will behave as previously, however if you are using a custom renderer, not provided by REST framework, then you may now need to add support for rendering `Decimal` instances to your renderer implementation.
-## ModelSerializers and reverse relationships
+## ModelSerializers and reverse relationships
The support for adding reverse relationships to the `fields` option on a `ModelSerializer` class means that the `get_related_field` and `get_nested_field` method signatures have now changed.
In the unlikely event that you're providing a custom serializer class, and implementing these methods you should note the new call signature for both methods is now `(self, model_field, related_model, to_many)`. For reverse relationships `model_field` will be `None`.
-The old-style signature will continue to function but will raise a `PendingDeprecationWarning`.
+The old-style signature will continue to function but will raise a `PendingDeprecationWarning`.
## View names and descriptions
@@ -211,7 +211,7 @@ The mechanics of how the names and descriptions used in the browseable API are g
If you've been customizing this behavior, for example perhaps to use `rst` markup for the browseable API, then you'll need to take a look at the implementation to see what updates you need to make.
-Note that the relevant methods have always been private APIs, and the docstrings called them out as intended to be deprecated.
+Note that the relevant methods have always been private APIs, and the docstrings called them out as intended to be deprecated.
---
diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md
index 90cbda4d..b32fe510 100644
--- a/docs/topics/3.0-announcement.md
+++ b/docs/topics/3.0-announcement.md
@@ -1,17 +1,3 @@
-## Pre-release notes:
-
-The 3.0 release is now ready for some tentative testing and upgrades for early adopters. You can install the development version directly from GitHub like so:
-
- pip install https://github.com/tomchristie/django-rest-framework/archive/master.zip
-
-See the [Version 3.0 GitHub issue](https://github.com/tomchristie/django-rest-framework/pull/1800) for more details on remaining work.
-
-**Your feedback on the upgrade process and 3.0 changes is hugely important!**
-
-Please do get in touch via twitter, IRC, a GitHub ticket, or the discussion group.
-
----
-
# REST framework 3.0
The 3.0 release of Django REST framework is the result of almost four years of iteration and refinement. It comprehensively addresses some of the previous remaining design issues in serializers, fields and the generic views.
@@ -20,6 +6,10 @@ This release is incremental in nature. There *are* some breaking API changes, an
The difference in quality of the REST framework API and implementation should make writing, maintaining and debugging your application far easier.
+3.0 is the first of three releases that have been funded by our recent [Kickstarter campaign](kickstarter.com/projects/tomchristie/django-rest-framework-3).
+
+As ever, a huge thank you to our many [wonderful sponsors](sponsors). If you're looking for a Django gig, and want to work with smart community-minded folks, you should probably check out that list and see who's hiring.
+
## New features
Notable features of this new release include:
@@ -32,6 +22,9 @@ Notable features of this new release include:
* Support for overriding how validation errors are handled by your API.
* A metadata API that allows you to customize how `OPTIONS` requests are handled by your API.
* A more compact JSON output with unicode style encoding turned on by default.
+* Templated based HTML form rendering for serializers. This will be finalized as public API in the upcoming 3.1 release.
+
+Significant new functionality continues to be planned for the 3.1 and 3.2 releases. These releases will correspond to the two [Kickstarter stretch goals](https://www.kickstarter.com/projects/tomchristie/django-rest-framework-3) - "Feature improvements" and "Admin interface". Further 3.x releases will present simple upgrades, without the same level of fundamental API changes necessary for the 3.0 release.
Below is an in-depth guide to the API changes and migration notes for 3.0.
@@ -140,6 +133,16 @@ The corresponding code would now look like this:
logging.info('Creating ticket "%s"' % name)
serializer.save(user=request.user) # Include the user when saving.
+#### Using `.is_valid(raise_exception=True)`
+
+The `.is_valid()` method now takes an optional boolean flag, `raise_exception`.
+
+Calling `.is_valid(raise_exception=True)` will cause a `ValidationError` to be raised if the serializer data contains validation errors. This error will be handled by REST framework's default exception handler, allowing you to remove error response handling from your view code.
+
+The handling and formatting of error responses may be altered globally by using the `EXCEPTION_HANDLER` settings key.
+
+This change also means it's now possible to alter the style of error responses used by the built-in generic views, without having to include mixin classes or other overrides.
+
#### Using `serializers.ValidationError`.
Previously `serializers.ValidationError` error was simply a synonym for `django.core.exceptions.ValidationError`. This has now been altered so that it inherits from the standard `APIException` base class.
@@ -155,7 +158,7 @@ We strongly recommend that you use the namespaced import style of `import serial
The `validate_<field_name>` method hooks that can be attached to serializer classes change their signature slightly and return type. Previously these would take a dictionary of all incoming data, and a key representing the field name, and would return a dictionary including the validated data for that field:
def validate_score(self, attrs, source):
- if attrs[score] % 10 != 0:
+ if attrs['score'] % 10 != 0:
raise serializers.ValidationError('This field should be a multiple of ten.')
return attrs
@@ -174,16 +177,43 @@ You can either return `non_field_errors` from the validate method by raising a s
def validate(self, attrs):
# serializer.errors == {'non_field_errors': ['A non field error']}
- raise serailizers.ValidationError('A non field error')
+ raise serializers.ValidationError('A non field error')
Alternatively if you want the errors to be against a specific field, use a dictionary of when instantiating the `ValidationError`, like so:
def validate(self, attrs):
# serializer.errors == {'my_field': ['A field error']}
- raise serailizers.ValidationError({'my_field': 'A field error'})
+ raise serializers.ValidationError({'my_field': 'A field error'})
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.
@@ -288,7 +318,7 @@ Alternatively, specify the field explicitly on the serializer class:
model = MyModel
fields = ('id', 'email', 'notes', 'is_admin')
-The `read_only_fields` option remains as a convenient shortcut for the more common case.
+The `read_only_fields` option remains as a convenient shortcut for the more common case.
#### Changes to `HyperlinkedModelSerializer`.
@@ -299,7 +329,7 @@ The `view_name` and `lookup_field` options have been moved to `PendingDeprecatio
model = MyModel
fields = ('url', 'email', 'notes', 'is_admin')
extra_kwargs = {
- 'url': {'lookup_field': 'uuid'}
+ 'url': {'lookup_field': 'uuid'}
}
Alternatively, specify the field explicitly on the serializer class:
@@ -349,7 +379,9 @@ The `ListSerializer` class has now been added, and allows you to create base ser
class MultipleUserSerializer(ListSerializer):
child = UserSerializer()
-You can also still use the `many=True` argument to serializer classes. It's worth noting that `many=True` argument transparently creates a `ListSerializer` instance, allowing the validation logic for list and non-list data to be cleanly separated in the REST framework codebase.
+You can also still use the `many=True` argument to serializer classes. It's worth noting that `many=True` argument transparently creates a `ListSerializer` instance, allowing the validation logic for list and non-list data to be cleanly separated in the REST framework codebase.
+
+You will typically want to *continue to use the existing `many=True` flag* rather than declaring `ListSerializer` classes explicitly, but declaring the classes explicitly can be useful if you need to write custom `create` or `update` methods for bulk updates, or provide for other custom behavior.
See also the new `ListField` class, which validates input in the same way, but does not include the serializer interfaces of `.is_valid()`, `.data`, `.save()` and so on.
@@ -369,7 +401,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.
@@ -419,7 +455,7 @@ Here's a complete example of our previous `HighScoreSerializer`, that's been upd
def to_internal_value(self, data):
score = data.get('score')
player_name = data.get('player_name')
-
+
# Perform the data validation.
if not score:
raise ValidationError({
@@ -433,7 +469,7 @@ Here's a complete example of our previous `HighScoreSerializer`, that's been upd
raise ValidationError({
'player_name': 'May not be more than 10 characters.'
})
-
+
# Return the validated values. This will be available as
# the `.validated_data` property.
return {
@@ -446,7 +482,7 @@ Here's a complete example of our previous `HighScoreSerializer`, that's been upd
'score': obj.score,
'player_name': obj.player_name
}
-
+
def create(self, validated_data):
return HighScore.objects.create(**validated_data)
@@ -454,7 +490,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):
"""
@@ -474,12 +510,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()
@@ -525,7 +561,20 @@ The `default` argument is also available and always implies that the field is no
#### Coercing output types.
-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.
+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.
@@ -668,7 +717,9 @@ The `UniqueTogetherValidator` should be applied to a serializer, and takes a `qu
#### The `UniqueForDateValidator` classes.
-**TODO: Needs documenting.**
+REST framework also now includes explicit validator classes for validating the `unique_for_date`, `unique_for_month`, and `unique_for_year` model field constraints. These are used internally instead of calling into `Model.full_clean()`.
+
+These classes are documented in the [Validators](../api-guide/validators.md) section of the documentation.
## Generic views
@@ -676,7 +727,7 @@ The `UniqueTogetherValidator` should be applied to a serializer, and takes a `qu
The view logic for the default method handlers has been significantly simplified, due to the new serializers API.
-#### Changes to pre/post save hooks.
+#### Changes to pre/post save hooks.
The `pre_save` and `post_save` hooks no longer exist, but are replaced with `perform_create(self, serializer)` and `perform_update(self, serializer)`.
@@ -726,7 +777,34 @@ This makes it far easier to use a different style for `OPTIONS` responses throug
## Serializers as HTML forms
-**TODO: Document this.**
+REST framework 3.0 includes templated HTML form rendering for serializers.
+
+This API should not yet be considered finalized, and will only be promoted to public API for the 3.1 release.
+
+Significant changes that you do need to be aware of include:
+
+* Nested HTML forms are now supported, for example, a `UserSerializer` with a nested `ProfileSerializer` will now render a nested `fieldset` when used in the browsable API.
+* Nested lists of HTML forms are not yet supported, but are planned for 3.1.
+* Because we now use templated HTML form generation, **the `widget` option is no longer available for serializer fields**. You can instead control the template that is used for a given field, by using the `style` dictionary.
+
+#### The `style` keyword argument for serializer fields.
+
+The `style` keyword argument can be used to pass through additional information from a serializer field, to the renderer class. In particular, the `HTMLFormRenderer` uses the `base_template` key to determine which template to render the field with.
+
+For example, to use a `textarea` control instead of the default `input` control, you would use the following…
+
+ additional_notes = serializers.CharField(
+ style={'base_template': 'text_area.html'}
+ )
+
+Similarly, to use a radio button control instead of the default `select` control, you would use the following…
+
+ color_channel = serializers.ChoiceField(
+ choices=['red', 'blue', 'green'],
+ style={'base_template': 'radio.html'}
+ )
+
+This API should be considered provisional, and there may be minor alterations with the incoming 3.1 release.
## API style
@@ -819,7 +897,12 @@ 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.
+
+* The serializer `ChoiceField` does not currently display nested choices, as was the case in 2.4. This will be address as part of 3.1.
+* Due to the new templated form rendering, the 'widget' option is no longer valid. This means there's no easy way of using third party "autocomplete" widgets for rendering select inputs that contain a large number of choices. You'll either need to use a regular select or a plain text input. We may consider addressing this in 3.1 or 3.2 if there's sufficient demand.
## What's coming next.
@@ -836,4 +919,5 @@ The 3.2 release is planned to introduce an alternative admin-style interface to
You can follow development on the GitHub site, where we use [milestones to indicate planning timescales](https://github.com/tomchristie/django-rest-framework/milestones).
-[mixins.py]: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py \ No newline at end of file
+[sponsors]: http://www.django-rest-framework.org/topics/kickstarter-announcement/#sponsors
+[mixins.py]: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py
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/contributing.md b/docs/topics/contributing.md
index 52f6e287..99f4fc3c 100644
--- a/docs/topics/contributing.md
+++ b/docs/topics/contributing.md
@@ -135,15 +135,15 @@ There are many great Markdown editors that make working with the documentation r
## Building the documentation
-To build the documentation, simply run the `mkdocs.py` script.
+To build the documentation, install MkDocs with `pip install mkdocs` and then run the following command.
- ./mkdocs.py
+ mkdocs build
-This will build the html output into the `html` directory.
+This will build the documentation into the `site` directory.
-You can build the documentation and open a preview in a browser window by using the `-p` flag.
+You can build the documentation and open a preview in a browser window by using the `serve` command.
- ./mkdocs.py -p
+ mkdocs serve
## Language style
@@ -152,7 +152,6 @@ Documentation should be in American English. The tone of the documentation is v
Some other tips:
* Keep paragraphs reasonably short.
-* Use double spacing after the end of sentences.
* Don't use abbreviations such as 'e.g.' but instead use the long form, such as 'For example'.
## Markdown style
@@ -198,21 +197,6 @@ If you want to draw attention to a note or warning, use a pair of enclosing line
---
-# Third party packages
-
-New features to REST framework are generally recommended to be implemented as third party libraries that are developed outside of the core framework. Ideally third party libraries should be properly documented and packaged, and made available on PyPI.
-
-## Getting started
-
-If you have some functionality that you would like to implement as a third party package it's worth contacting the [discussion group][google-group] as others may be willing to get involved. We strongly encourage third party package development and will always try to prioritize time spent helping their development, documentation and packaging.
-
-We recommend the [`django-reusable-app`][django-reusable-app] template as a good resource for getting up and running with implementing a third party Django package.
-
-## Linking to your package
-
-Once your package is decently documented and available on PyPI open a pull request or issue, and we'll add a link to it from the main REST framework documentation. You can add your package under **Third party packages** of the API Guide section that best applies, like [Authentication][authentication] or [Permissions][permissions]. You can also link your package under the [Third Party Resources][third-party-resources] section.
-
-We also suggest adding it to the [REST Framework][rest-framework-grid] grid on Django Packages.
[cite]: http://www.w3.org/People/Berners-Lee/FAQ.html
[code-of-conduct]: https://www.djangoproject.com/conduct/
@@ -226,8 +210,3 @@ We also suggest adding it to the [REST Framework][rest-framework-grid] grid on D
[markdown]: http://daringfireball.net/projects/markdown/basics
[docs]: https://github.com/tomchristie/django-rest-framework/tree/master/docs
[mou]: http://mouapp.com/
-[django-reusable-app]: https://github.com/dabapps/django-reusable-app
-[authentication]: ../api-guide/authentication.md
-[permissions]: ../api-guide/permissions.md
-[third-party-resources]: third-party-resources.md
-[rest-framework-grid]: https://www.djangopackages.com/grids/g/django-rest-framework/
diff --git a/docs/topics/documenting-your-api.md b/docs/topics/documenting-your-api.md
index e20f9712..d65e251f 100644
--- a/docs/topics/documenting-your-api.md
+++ b/docs/topics/documenting-your-api.md
@@ -54,7 +54,7 @@ The title that is used in the browsable API is generated from the view class nam
For example, the view `UserListView`, will be named `User List` when presented in the browsable API.
-When working with viewsets, an appropriate suffix is appended to each generated view. For example, the view set `UserViewSet` will generate views named `User List` and `User Instance`.
+When working with viewsets, an appropriate suffix is appended to each generated view. For example, the view set `UserViewSet` will generate views named `User List` and `User Instance`.
#### Setting the description
@@ -65,9 +65,9 @@ If the python `markdown` library is installed, then [markdown syntax][markdown]
class AccountListView(views.APIView):
"""
Returns a list of all **active** accounts in the system.
-
+
For more details on how accounts are activated please [see here][ref].
-
+
[ref]: http://example.com/activating-accounts
"""
@@ -84,7 +84,7 @@ You can modify the response behavior to `OPTIONS` requests by overriding the `me
def metadata(self, request):
"""
Don't include the view description in OPTIONS responses.
- """
+ """
data = super(ExampleView, self).metadata(request)
data.pop('description')
return data
diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md
index 7d1f6d0e..91ead751 100644
--- a/docs/topics/kickstarter-announcement.md
+++ b/docs/topics/kickstarter-announcement.md
@@ -43,20 +43,20 @@ We've now blazed way past all our goals, with a staggering £30,000 (~$50,000),
Our platinum sponsors have each made a hugely substantial contribution to the future development of Django REST framework, and I simply can't thank them enough.
<ul class="sponsor diamond">
-<li><a href="https://www.eventbrite.com/" rel="nofollow" style="background-image:url(../img/sponsors/0-eventbrite.png);">Eventbrite</a></li>
+<li><a href="https://www.eventbrite.com/" rel="nofollow" style="background-image:url(../../img/sponsors//0-eventbrite.png);">Eventbrite</a></li>
</ul>
<ul class="sponsor platinum">
-<li><a href="https://www.divio.ch/" rel="nofollow" style="background-image:url(../img/sponsors/1-divio.png);">Divio</a></li>
-<li><a href="http://company.onlulu.com/en/" rel="nofollow" style="background-image:url(../img/sponsors/1-lulu.png);">Lulu</a></li>
-<li><a href="https://p.ota.to/" rel="nofollow" style="background-image:url(../img/sponsors/1-potato.png);">Potato</a></li>
-<li><a href="http://www.wiredrive.com/" rel="nofollow" style="background-image:url(../img/sponsors/1-wiredrive.png);">Wiredrive</a></li>
-<li><a href="http://www.cyaninc.com/" rel="nofollow" style="background-image:url(../img/sponsors/1-cyan.png);">Cyan</a></li>
-<li><a href="https://www.runscope.com/" rel="nofollow" style="background-image:url(../img/sponsors/1-runscope.png);">Runscope</a></li>
-<li><a href="http://simpleenergy.com/" rel="nofollow" style="background-image:url(../img/sponsors/1-simple-energy.png);">Simple Energy</a></li>
-<li><a href="http://vokalinteractive.com/" rel="nofollow" style="background-image:url(../img/sponsors/1-vokal_interactive.png);">VOKAL Interactive</a></li>
-<li><a href="http://www.purplebit.com/" rel="nofollow" style="background-image:url(../img/sponsors/1-purplebit.png);">Purple Bit</a></li>
-<li><a href="http://www.kuwaitnet.net/" rel="nofollow" style="background-image:url(../img/sponsors/1-kuwaitnet.png);">KuwaitNET</a></li>
+<li><a href="https://www.divio.ch/" rel="nofollow" style="background-image:url(../../img/sponsors//1-divio.png);">Divio</a></li>
+<li><a href="http://company.onlulu.com/en/" rel="nofollow" style="background-image:url(../../img/sponsors//1-lulu.png);">Lulu</a></li>
+<li><a href="https://p.ota.to/" rel="nofollow" style="background-image:url(../../img/sponsors//1-potato.png);">Potato</a></li>
+<li><a href="http://www.wiredrive.com/" rel="nofollow" style="background-image:url(../../img/sponsors//1-wiredrive.png);">Wiredrive</a></li>
+<li><a href="http://www.cyaninc.com/" rel="nofollow" style="background-image:url(../../img/sponsors//1-cyan.png);">Cyan</a></li>
+<li><a href="https://www.runscope.com/" rel="nofollow" style="background-image:url(../../img/sponsors//1-runscope.png);">Runscope</a></li>
+<li><a href="http://simpleenergy.com/" rel="nofollow" style="background-image:url(../../img/sponsors//1-simple-energy.png);">Simple Energy</a></li>
+<li><a href="http://vokalinteractive.com/" rel="nofollow" style="background-image:url(../../img/sponsors//1-vokal_interactive.png);">VOKAL Interactive</a></li>
+<li><a href="http://www.purplebit.com/" rel="nofollow" style="background-image:url(../../img/sponsors//1-purplebit.png);">Purple Bit</a></li>
+<li><a href="http://www.kuwaitnet.net/" rel="nofollow" style="background-image:url(../../img/sponsors//1-kuwaitnet.png);">KuwaitNET</a></li>
</ul>
<div style="clear: both"></div>
@@ -68,31 +68,31 @@ Our platinum sponsors have each made a hugely substantial contribution to the fu
Our gold sponsors include companies large and small. Many thanks for their significant funding of the project and their commitment to sustainable open-source development.
<ul class="sponsor gold">
-<li><a href="https://laterpay.net/" rel="nofollow" style="background-image:url(../img/sponsors/2-laterpay.png);">LaterPay</a></li>
-<li><a href="https://www.schubergphilis.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-schuberg_philis.png);">Schuberg Philis</a></li>
-<li><a href="http://prorenata.se/" rel="nofollow" style="background-image:url(../img/sponsors/2-prorenata.png);">ProReNata AB</a></li>
-<li><a href="https://www.sgawebsites.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-sga.png);">SGA Websites</a></li>
-<li><a href="http://www.sirono.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-sirono.png);">Sirono</a></li>
-<li><a href="http://www.vinta.com.br/" rel="nofollow" style="background-image:url(../img/sponsors/2-vinta.png);">Vinta Software Studio</a></li>
-<li><a href="http://www.rapasso.nl/index.php/en" rel="nofollow" style="background-image:url(../img/sponsors/2-rapasso.png);">Rapasso</a></li>
-<li><a href="https://mirusresearch.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-mirus_research.png);">Mirus Research</a></li>
-<li><a href="http://hipolabs.com" rel="nofollow" style="background-image:url(../img/sponsors/2-hipo.png);">Hipo</a></li>
-<li><a href="http://www.byte.nl" rel="nofollow" style="background-image:url(../img/sponsors/2-byte.png);">Byte</a></li>
-<li><a href="http://lightningkite.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-lightning_kite.png);">Lightning Kite</a></li>
-<li><a href="https://opbeat.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-opbeat.png);">Opbeat</a></li>
-<li><a href="https://koordinates.com" rel="nofollow" style="background-image:url(../img/sponsors/2-koordinates.png);">Koordinates</a></li>
-<li><a href="http://pulsecode.ca" rel="nofollow" style="background-image:url(../img/sponsors/2-pulsecode.png);">Pulsecode Inc.</a></li>
-<li><a href="http://singinghorsestudio.com" rel="nofollow" style="background-image:url(../img/sponsors/2-singing-horse.png);">Singing Horse Studio Ltd.</a></li>
-<li><a href="https://www.heroku.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-heroku.png);">Heroku</a></li>
-<li><a href="https://www.galileo-press.de/" rel="nofollow" style="background-image:url(../img/sponsors/2-galileo_press.png);">Galileo Press</a></li>
-<li><a href="http://www.securitycompass.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-security_compass.png);">Security Compass</a></li>
-<li><a href="https://www.djangoproject.com/foundation/" rel="nofollow" style="background-image:url(../img/sponsors/2-django.png);">Django Software Foundation</a></li>
-<li><a href="http://www.hipflaskapp.com" rel="nofollow" style="background-image:url(../img/sponsors/2-hipflask.png);">Hipflask</a></li>
-<li><a href="http://www.crate.io/" rel="nofollow" style="background-image:url(../img/sponsors/2-crate.png);">Crate</a></li>
-<li><a href="http://crypticocorp.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-cryptico.png);">Cryptico Corp</a></li>
-<li><a href="http://www.nexthub.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-nexthub.png);">NextHub</a></li>
-<li><a href="https://www.compile.com/" rel="nofollow" style="background-image:url(../img/sponsors/2-compile.png);">Compile</a></li>
-<li><a href="http://wusawork.org" rel="nofollow" style="background-image:url(../img/sponsors/2-wusawork.png);">WusaWork</a></li>
+<li><a href="https://laterpay.net/" rel="nofollow" style="background-image:url(../../img/sponsors//2-laterpay.png);">LaterPay</a></li>
+<li><a href="https://www.schubergphilis.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-schuberg_philis.png);">Schuberg Philis</a></li>
+<li><a href="http://prorenata.se/" rel="nofollow" style="background-image:url(../../img/sponsors//2-prorenata.png);">ProReNata AB</a></li>
+<li><a href="https://www.sgawebsites.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-sga.png);">SGA Websites</a></li>
+<li><a href="http://www.sirono.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-sirono.png);">Sirono</a></li>
+<li><a href="http://www.vinta.com.br/" rel="nofollow" style="background-image:url(../../img/sponsors//2-vinta.png);">Vinta Software Studio</a></li>
+<li><a href="http://www.rapasso.nl/index.php/en" rel="nofollow" style="background-image:url(../../img/sponsors//2-rapasso.png);">Rapasso</a></li>
+<li><a href="https://mirusresearch.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-mirus_research.png);">Mirus Research</a></li>
+<li><a href="http://hipolabs.com" rel="nofollow" style="background-image:url(../../img/sponsors//2-hipo.png);">Hipo</a></li>
+<li><a href="http://www.byte.nl" rel="nofollow" style="background-image:url(../../img/sponsors//2-byte.png);">Byte</a></li>
+<li><a href="http://lightningkite.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-lightning_kite.png);">Lightning Kite</a></li>
+<li><a href="https://opbeat.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-opbeat.png);">Opbeat</a></li>
+<li><a href="https://koordinates.com" rel="nofollow" style="background-image:url(../../img/sponsors//2-koordinates.png);">Koordinates</a></li>
+<li><a href="http://pulsecode.ca" rel="nofollow" style="background-image:url(../../img/sponsors//2-pulsecode.png);">Pulsecode Inc.</a></li>
+<li><a href="http://singinghorsestudio.com" rel="nofollow" style="background-image:url(../../img/sponsors//2-singing-horse.png);">Singing Horse Studio Ltd.</a></li>
+<li><a href="https://www.heroku.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-heroku.png);">Heroku</a></li>
+<li><a href="https://www.galileo-press.de/" rel="nofollow" style="background-image:url(../../img/sponsors//2-galileo_press.png);">Galileo Press</a></li>
+<li><a href="http://www.securitycompass.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-security_compass.png);">Security Compass</a></li>
+<li><a href="https://www.djangoproject.com/foundation/" rel="nofollow" style="background-image:url(../../img/sponsors//2-django.png);">Django Software Foundation</a></li>
+<li><a href="http://www.hipflaskapp.com" rel="nofollow" style="background-image:url(../../img/sponsors//2-hipflask.png);">Hipflask</a></li>
+<li><a href="http://www.crate.io/" rel="nofollow" style="background-image:url(../../img/sponsors//2-crate.png);">Crate</a></li>
+<li><a href="http://crypticocorp.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-cryptico.png);">Cryptico Corp</a></li>
+<li><a href="http://www.nexthub.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-nexthub.png);">NextHub</a></li>
+<li><a href="https://www.compile.com/" rel="nofollow" style="background-image:url(../../img/sponsors//2-compile.png);">Compile</a></li>
+<li><a href="http://wusawork.org" rel="nofollow" style="background-image:url(../../img/sponsors//2-wusawork.png);">WusaWork</a></li>
<li><a href="http://envisionlinux.org/blog" rel="nofollow">Envision Linux</a></li>
</ul>
@@ -105,41 +105,41 @@ Our gold sponsors include companies large and small. Many thanks for their signi
The serious financial contribution that our silver sponsors have made is very much appreciated. I'd like to say a particular thank&nbsp;you to individuals who have choosen to privately support the project at this level.
<ul class="sponsor silver">
-<li><a href="http://www.imtapps.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-imt_computer_services.png);">IMT Computer Services</a></li>
-<li><a href="http://wildfish.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-wildfish.png);">Wildfish</a></li>
-<li><a href="http://www.thermondo.de/" rel="nofollow" style="background-image:url(../img/sponsors/3-thermondo-gmbh.png);">Thermondo GmbH</a></li>
-<li><a href="http://providenz.fr/" rel="nofollow" style="background-image:url(../img/sponsors/3-providenz.png);">Providenz</a></li>
-<li><a href="https://www.alwaysdata.com" rel="nofollow" style="background-image:url(../img/sponsors/3-alwaysdata.png);">alwaysdata.com</a></li>
-<li><a href="http://www.triggeredmessaging.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-triggered_messaging.png);">Triggered Messaging</a></li>
-<li><a href="https://www.ipushpull.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-ipushpull.png);">PushPull Technology Ltd</a></li>
-<li><a href="http://www.transcode.de/" rel="nofollow" style="background-image:url(../img/sponsors/3-transcode.png);">Transcode</a></li>
-<li><a href="https://garfo.io/" rel="nofollow" style="background-image:url(../img/sponsors/3-garfo.png);">Garfo</a></li>
-<li><a href="https://goshippo.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-shippo.png);">Shippo</a></li>
-<li><a href="http://www.gizmag.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-gizmag.png);">Gizmag</a></li>
-<li><a href="http://www.tivix.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-tivix.png);">Tivix</a></li>
-<li><a href="http://www.safaribooksonline.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-safari.png);">Safari</a></li>
-<li><a href="http://brightloop.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-brightloop.png);">Bright Loop</a></li>
-<li><a href="http://www.aba-systems.com.au/" rel="nofollow" style="background-image:url(../img/sponsors/3-aba.png);">ABA Systems</a></li>
-<li><a href="http://beefarm.ru/" rel="nofollow" style="background-image:url(../img/sponsors/3-beefarm.png);">beefarm.ru</a></li>
-<li><a href="http://www.vzzual.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-vzzual.png);">Vzzual.com</a></li>
-<li><a href="http://infinite-code.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-infinite_code.png);">Infinite Code</a></li>
-<li><a href="http://crosswordtracker.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-crosswordtracker.png);">Crossword Tracker</a></li>
-<li><a href="https://www.pkgfarm.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-pkgfarm.png);">PkgFarm</a></li>
-<li><a href="http://life.tl/" rel="nofollow" style="background-image:url(../img/sponsors/3-life_the_game.png);">Life. The Game.</a></li>
-<li><a href="http://blimp.io/" rel="nofollow" style="background-image:url(../img/sponsors/3-blimp.png);">Blimp</a></li>
-<li><a href="http://pathwright.com" rel="nofollow" style="background-image:url(../img/sponsors/3-pathwright.png);">Pathwright</a></li>
-<li><a href="http://fluxility.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-fluxility.png);">Fluxility</a></li>
-<li><a href="http://teonite.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-teonite.png);">Teonite</a></li>
-<li><a href="http://trackmaven.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-trackmaven.png);">TrackMaven</a></li>
-<li><a href="http://www.phurba.net/" rel="nofollow" style="background-image:url(../img/sponsors/3-phurba.png);">Phurba</a></li>
-<li><a href="http://www.nephila.co.uk/" rel="nofollow" style="background-image:url(../img/sponsors/3-nephila.png);">Nephila</a></li>
-<li><a href="http://www.aditium.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-aditium.png);">Aditium</a></li>
-<li><a href="http://www.eyesopen.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-openeye.png);">OpenEye Scientific Software</a></li>
-<li><a href="https://holvi.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-holvi.png);">Holvi</a></li>
-<li><a href="http://cantemo.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-cantemo.gif);">Cantemo</a></li>
-<li><a href="https://www.makespace.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-makespace.png);">MakeSpace</a></li>
-<li><a href="https://www.ax-semantics.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-ax_semantics.png);">AX Semantics</a></li>
-<li><a href="http://istrategylabs.com/" rel="nofollow" style="background-image:url(../img/sponsors/3-isl.png);">ISL</a></li>
+<li><a href="http://www.imtapps.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-imt_computer_services.png);">IMT Computer Services</a></li>
+<li><a href="http://wildfish.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-wildfish.png);">Wildfish</a></li>
+<li><a href="http://www.thermondo.de/" rel="nofollow" style="background-image:url(../../img/sponsors//3-thermondo-gmbh.png);">Thermondo GmbH</a></li>
+<li><a href="http://providenz.fr/" rel="nofollow" style="background-image:url(../../img/sponsors//3-providenz.png);">Providenz</a></li>
+<li><a href="https://www.alwaysdata.com" rel="nofollow" style="background-image:url(../../img/sponsors//3-alwaysdata.png);">alwaysdata.com</a></li>
+<li><a href="http://www.triggeredmessaging.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-triggered_messaging.png);">Triggered Messaging</a></li>
+<li><a href="https://www.ipushpull.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-ipushpull.png);">PushPull Technology Ltd</a></li>
+<li><a href="http://www.transcode.de/" rel="nofollow" style="background-image:url(../../img/sponsors//3-transcode.png);">Transcode</a></li>
+<li><a href="https://garfo.io/" rel="nofollow" style="background-image:url(../../img/sponsors//3-garfo.png);">Garfo</a></li>
+<li><a href="https://goshippo.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-shippo.png);">Shippo</a></li>
+<li><a href="http://www.gizmag.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-gizmag.png);">Gizmag</a></li>
+<li><a href="http://www.tivix.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-tivix.png);">Tivix</a></li>
+<li><a href="http://www.safaribooksonline.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-safari.png);">Safari</a></li>
+<li><a href="http://brightloop.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-brightloop.png);">Bright Loop</a></li>
+<li><a href="http://www.aba-systems.com.au/" rel="nofollow" style="background-image:url(../../img/sponsors//3-aba.png);">ABA Systems</a></li>
+<li><a href="http://beefarm.ru/" rel="nofollow" style="background-image:url(../../img/sponsors//3-beefarm.png);">beefarm.ru</a></li>
+<li><a href="http://www.vzzual.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-vzzual.png);">Vzzual.com</a></li>
+<li><a href="http://infinite-code.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-infinite_code.png);">Infinite Code</a></li>
+<li><a href="http://crosswordtracker.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-crosswordtracker.png);">Crossword Tracker</a></li>
+<li><a href="https://www.pkgfarm.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-pkgfarm.png);">PkgFarm</a></li>
+<li><a href="http://life.tl/" rel="nofollow" style="background-image:url(../../img/sponsors//3-life_the_game.png);">Life. The Game.</a></li>
+<li><a href="http://blimp.io/" rel="nofollow" style="background-image:url(../../img/sponsors//3-blimp.png);">Blimp</a></li>
+<li><a href="http://pathwright.com" rel="nofollow" style="background-image:url(../../img/sponsors//3-pathwright.png);">Pathwright</a></li>
+<li><a href="http://fluxility.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-fluxility.png);">Fluxility</a></li>
+<li><a href="http://teonite.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-teonite.png);">Teonite</a></li>
+<li><a href="http://trackmaven.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-trackmaven.png);">TrackMaven</a></li>
+<li><a href="http://www.phurba.net/" rel="nofollow" style="background-image:url(../../img/sponsors//3-phurba.png);">Phurba</a></li>
+<li><a href="http://www.nephila.co.uk/" rel="nofollow" style="background-image:url(../../img/sponsors//3-nephila.png);">Nephila</a></li>
+<li><a href="http://www.aditium.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-aditium.png);">Aditium</a></li>
+<li><a href="http://www.eyesopen.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-openeye.png);">OpenEye Scientific Software</a></li>
+<li><a href="https://holvi.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-holvi.png);">Holvi</a></li>
+<li><a href="http://cantemo.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-cantemo.gif);">Cantemo</a></li>
+<li><a href="https://www.makespace.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-makespace.png);">MakeSpace</a></li>
+<li><a href="https://www.ax-semantics.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-ax_semantics.png);">AX Semantics</a></li>
+<li><a href="http://istrategylabs.com/" rel="nofollow" style="background-image:url(../../img/sponsors//3-isl.png);">ISL</a></li>
</ul>
<div style="clear: both; padding-bottom: 40px;"></div>
@@ -160,4 +160,4 @@ The following individuals made a significant financial contribution to the devel
### Supporters
-There were also almost 300 further individuals choosing to help fund the project at other levels or choosing to give anonymously. Again, thank you, thank you, thank you! \ No newline at end of file
+There were also almost 300 further individuals choosing to help fund the project at other levels or choosing to give anonymously. Again, thank you, thank you, thank you!
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index 88780c3f..53187589 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -63,7 +63,7 @@ You can determine your currently installed version using `pip freeze`:
* Bugfix: Fix migration in `authtoken` application.
* Bugfix: Allow selection of integer keys in nested choices.
* Bugfix: Return `None` instead of `'None'` in `CharField` with `allow_none=True`.
-* Bugfix: Ensure custom model fields map to equivelent serializer fields more reliably.
+* Bugfix: Ensure custom model fields map to equivelent serializer fields more reliably.
* Bugfix: `DjangoFilterBackend` no longer quietly changes queryset ordering.
### 2.4.2
@@ -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/topics/rest-framework-2-announcement.md b/docs/topics/rest-framework-2-announcement.md
index f1060d90..a7746932 100644
--- a/docs/topics/rest-framework-2-announcement.md
+++ b/docs/topics/rest-framework-2-announcement.md
@@ -8,7 +8,7 @@ What it is, and why you should care.
---
-**Announcement:** REST framework 2 released - Tue 30th Oct 2012
+**Announcement:** REST framework 2 released - Tue 30th Oct 2012
---
@@ -37,7 +37,7 @@ REST framework 2 includes a totally re-worked serialization engine, that was ini
* A declarative serialization API, that mirrors Django's `Forms`/`ModelForms` API.
* Structural concerns are decoupled from encoding concerns.
* Able to support rendering and parsing to many formats, including both machine-readable representations and HTML forms.
-* Validation that can be mapped to obvious and comprehensive error responses.
+* Validation that can be mapped to obvious and comprehensive error responses.
* Serializers that support both nested, flat, and partially-nested representations.
* Relationships that can be expressed as primary keys, hyperlinks, slug fields, and other custom representations.
diff --git a/docs/topics/rest-hypermedia-hateoas.md b/docs/topics/rest-hypermedia-hateoas.md
index 4e3ccf92..7e6d2408 100644
--- a/docs/topics/rest-hypermedia-hateoas.md
+++ b/docs/topics/rest-hypermedia-hateoas.md
@@ -1,12 +1,12 @@
# REST, Hypermedia & HATEOAS
-> You keep using that word "REST". I do not think it means what you think it means.
+> You keep using that word "REST". I do not think it means what you think it means.
>
> &mdash; Mike Amundsen, [REST fest 2012 keynote][cite].
-First off, the disclaimer. The name "Django REST framework" was chosen simply to sure the project would be easily found by developers. Throughout the documentation we try to use the more simple and technically correct terminology of "Web APIs".
+First off, the disclaimer. The name "Django REST framework" was decided back in early 2011 and was chosen simply to sure the project would be easily found by developers. Throughout the documentation we try to use the more simple and technically correct terminology of "Web APIs".
-If you are serious about designing a Hypermedia APIs, you should look to resources outside of this documentation to help inform your design choices.
+If you are serious about designing a Hypermedia API, you should look to resources outside of this documentation to help inform your design choices.
The following fall into the "required reading" category.
@@ -32,7 +32,7 @@ REST framework also includes [serialization] and [parser]/[renderer] components
## What REST framework doesn't provide.
-What REST framework doesn't do is give you is machine readable hypermedia formats such as [HAL][hal], [Collection+JSON][collection], [JSON API][json-api] or HTML [microformats] by default, or the ability to auto-magically create fully HATEOAS style APIs that include hypermedia-based form descriptions and semantically labelled hyperlinks. Doing so would involve making opinionated choices about API design that should really remain outside of the framework's scope.
+What REST framework doesn't do is give you is machine readable hypermedia formats such as [HAL][hal], [Collection+JSON][collection], [JSON API][json-api] or HTML [microformats] by default, or the ability to auto-magically create fully HATEOAS style APIs that include hypermedia-based form descriptions and semantically labelled hyperlinks. Doing so would involve making opinionated choices about API design that should really remain outside of the framework's scope.
[cite]: http://vimeo.com/channels/restfest/page:2
[dissertation]: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
diff --git a/docs/topics/third-party-resources.md b/docs/topics/third-party-resources.md
index 0317dd64..efa0b91f 100644
--- a/docs/topics/third-party-resources.md
+++ b/docs/topics/third-party-resources.md
@@ -1,92 +1,322 @@
# Third Party Resources
-Django REST Framework has a growing community of developers, packages, and resources.
+## About Third Party Packages
+
+Third Party Packages allow developers to share code that extends the functionality of Django REST framework, in order to support additional use-cases.
+
+We **support**, **encourage** and **strongly favor** the creation of Third Party Packages to encapsulate new behavior rather than adding additional functionality directly to Django REST Framework.
+
+We aim to make creating third party packages as easy as possible, whilst keeping a **simple** and **well maintained** core API. By promoting third party packages we ensure that the responsibility for a package remains with its author. If a package proves suitably popular it can always be considered for inclusion into the core REST framework.
+
+If you have an idea for a new feature please consider how it may be packaged as a Third Party Package. We're always happy to discuss ideas on the [Mailing List][discussion-group].
+
+## How to create a Third Party Package
+
+### Creating your package
+
+You can use [this cookiecutter template][cookiecutter] for creating reusable Django REST Framework packages quickly. Cookiecutter creates projects from project templates. While optional, this cookiecutter template includes best practices from Django REST framework and other packages, as well as a Travis CI configuration, Tox configuration, and a sane setup.py for easy PyPI registration/distribution.
+
+Note: Let us know if you have an alternate cookiecuter package so we can also link to it.
+
+#### Running the initial cookiecutter command
+
+To run the initial cookiecutter command, you'll first need to install the Python `cookiecutter` package.
+
+ $ pip install cookiecutter
+
+Once `cookiecutter` is installed just run the following to create a new project.
+
+ $ cookiecutter gh:jpadilla/cookiecutter-django-rest-framework
+
+You'll be prompted for some questions, answer them, then it'll create your Python package in the current working directory based on those values.
+
+ full_name (default is "Your full name here")? Johnny Appleseed
+ email (default is "you@example.com")? jappleseed@example.com
+ github_username (default is "yourname")? jappleseed
+ pypi_project_name (default is "dj-package")? djangorestframework-custom-auth
+ repo_name (default is "dj-package")? django-rest-framework-custom-auth
+ app_name (default is "djpackage")? custom_auth
+ project_short_description (default is "Your project description goes here")?
+ year (default is "2014")?
+ version (default is "0.1.0")?
+
+#### Getting it onto GitHub
+
+To put your project up on GitHub, you'll need a repository for it to live in. You can create a new repository [here][new-repo]. If you need help, check out the [Create A Repo][create-a-repo] article on GitHub.
+
+
+#### Adding to Travis CI
+
+We recommend using [Travis CI][travis-ci], a hosted continuous integration service which integrates well with GitHub and is free for public repositories.
+
+To get started with Travis CI, [sign in][travis-ci] with your GitHub account. Once you're signed in, go to your [profile page][travis-profile] and enable the service hook for the repository you want.
+
+If you use the cookiecutter template, your project will already contain a `.travis.yml` file which Travis CI will use to build your project and run tests. By default, builds are triggered everytime you push to your repository or create Pull Request.
+
+#### Uploading to PyPI
+
+Once you've got at least a prototype working and tests running, you should publish it on PyPI to allow others to install it via `pip`.
+
+You must [register][pypi-register] an account before publishing to PyPI.
+
+To register your package on PyPI run the following command.
+
+ $ python setup.py register
+
+If this is the first time publishing to PyPI, you'll be prompted to login.
+
+Note: Before publishing you'll need to make sure you have the latest pip that supports `wheel` as well as install the `wheel` package.
+
+ $ pip install --upgrade pip
+ $ pip install wheel
+
+After this, every time you want to release a new version on PyPI just run the following command.
+
+ $ python setup.py publish
+ You probably want to also tag the version now:
+ git tag -a {0} -m 'version 0.1.0'
+ git push --tags
+
+After releasing a new version to PyPI, it's always a good idea to tag the version and make available as a GitHub Release.
+
+We recommend to follow [Semantic Versioning][semver] for your package's versions.
+
+### Development
+
+#### Version requirements
+
+The cookiecutter template assumes a set of supported versions will be provided for Python and Django. Make sure you correctly update your requirements, docs, `tox.ini`, `.travis.yml`, and `setup.py` to match the set of versions you wish to support.
+
+#### Tests
+
+The cookiecutter template includes a `runtests.py` which uses the `pytest` package as a test runner.
+
+Before running, you'll need to install a couple test requirements.
+
+ $ pip install -r requirements-test.txt
-Check out a grid detailing all the packages and ecosystem around Django REST Framework at [Django Packages](https://www.djangopackages.com/grids/g/django-rest-framework/).
+Once requirements installed, you can run `runtests.py`.
-To submit new content, [open an issue](https://github.com/tomchristie/django-rest-framework/issues/new) or [create a pull request](https://github.com/tomchristie/django-rest-framework/).
+ $ ./runtests.py
-## Libraries and Extensions
+Run using a more concise output style.
+
+ $ ./runtests.py -q
+
+Run the tests using a more concise output style, no coverage, no flake8.
+
+ $ ./runtests.py --fast
+
+Don't run the flake8 code linting.
+
+ $ ./runtests.py --nolint
+
+Only run the flake8 code linting, don't run the tests.
+
+ $ ./runtests.py --lintonly
+
+Run the tests for a given test case.
+
+ $ ./runtests.py MyTestCase
+
+Run the tests for a given test method.
+
+ $ ./runtests.py MyTestCase.test_this_method
+
+Shorter form to run the tests for a given test method.
+
+ $ ./runtests.py test_this_method
+
+To run your tests against multiple versions of Python as different versions of requirements such as Django we recommend using `tox`. [Tox][tox-docs] is a generic virtualenv management and test command line tool.
+
+First, install `tox` globally.
+
+ $ pip install tox
+
+To run `tox`, just simply run:
+
+ $ tox
+
+To run a particular `tox` environment:
+
+ $ tox -e envlist
+
+`envlist` is a comma-separated value to that specifies the environments to run tests against. To view a list of all possible test environments, run:
+
+ $ tox -l
+
+#### Version compatibility
+
+Sometimes, in order to ensure your code works on various different versions of Django, Python or third party libraries, you'll need to run slightly different code depending on the environment. Any code that branches in this way should be isolated into a `compat.py` module, and should provide a single common interface that the rest of the codebase can use.
+
+Check out Django REST framework's [compat.py][drf-compat] for an example.
+
+### Once your package is available
+
+Once your package is decently documented and available on PyPI, you might want share it with others that might find it useful.
+
+#### Adding to the Django REST framework grid
+
+We suggest adding your package to the [REST Framework][rest-framework-grid] grid on Django Packages.
+
+#### Adding to the Django REST framework docs
+
+Create a [Pull Request][drf-create-pr] or [Issue][drf-create-issue] on GitHub, and we'll add a link to it from the main REST framework documentation. You can add your package under **Third party packages** of the API Guide section that best applies, like [Authentication][authentication] or [Permissions][permissions]. You can also link your package under the [Third Party Resources][third-party-resources] section.
+
+#### Announce on the discussion group.
+
+You can also let others know about your package through the [discussion group][discussion-group].
+
+## Existing Third Party Packages
+
+Django REST Framework has a growing community of developers, packages, and resources.
+
+Check out a grid detailing all the packages and ecosystem around Django REST Framework at [Django Packages][rest-framework-grid].
+
+To submit new content, [open an issue][drf-create-issue] or [create a pull request][drf-create-pr].
### Authentication
-* [djangorestframework-digestauth](https://github.com/juanriaza/django-rest-framework-digestauth) - Provides Digest Access Authentication support.
-* [django-oauth-toolkit](https://github.com/evonove/django-oauth-toolkit) - Provides OAuth 2.0 support.
-* [doac](https://github.com/Rediker-Software/doac) - Provides OAuth 2.0 support.
-* [djangorestframework-jwt](https://github.com/GetBlimp/django-rest-framework-jwt) - Provides JSON Web Token Authentication support.
-* [hawkrest](https://github.com/kumar303/hawkrest) - Provides Hawk HTTP Authorization.
-* [djangorestframework-httpsignature](https://github.com/etoccalino/django-rest-framework-httpsignature) - Provides an easy to use HTTP Signature Authentication mechanism.
-* [djoser](https://github.com/sunscrapers/djoser) - Provides a set of views to handle basic actions such as registration, login, logout, password reset and account activation.
+* [djangorestframework-digestauth][djangorestframework-digestauth] - Provides Digest Access Authentication support.
+* [django-oauth-toolkit][django-oauth-toolkit] - Provides OAuth 2.0 support.
+* [doac][doac] - Provides OAuth 2.0 support.
+* [djangorestframework-jwt][djangorestframework-jwt] - Provides JSON Web Token Authentication support.
+* [hawkrest][hawkrest] - Provides Hawk HTTP Authorization.
+* [djangorestframework-httpsignature][djangorestframework-httpsignature] - Provides an easy to use HTTP Signature Authentication mechanism.
+* [djoser][djoser] - Provides a set of views to handle basic actions such as registration, login, logout, password reset and account activation.
### Permissions
-* [drf-any-permissions](https://github.com/kevin-brown/drf-any-permissions) - Provides alternative permission handling.
-* [djangorestframework-composed-permissions](https://github.com/niwibe/djangorestframework-composed-permissions) - Provides a simple way to define complex permissions.
-* [rest_condition](https://github.com/caxap/rest_condition) - Another extension for building complex permissions in a simple and convenient way.
+* [drf-any-permissions][drf-any-permissions] - Provides alternative permission handling.
+* [djangorestframework-composed-permissions][djangorestframework-composed-permissions] - Provides a simple way to define complex permissions.
+* [rest_condition][rest-condition] - Another extension for building complex permissions in a simple and convenient way.
### Serializers
-* [django-rest-framework-mongoengine](https://github.com/umutbozkurt/django-rest-framework-mongoengine) - Serializer class that supports using MongoDB as the storage layer for Django REST framework.
-* [djangorestframework-gis](https://github.com/djangonauts/django-rest-framework-gis) - Geographic add-ons
-* [djangorestframework-hstore](https://github.com/djangonauts/django-rest-framework-hstore) - Serializer class to support django-hstore DictionaryField model field and its schema-mode feature.
+* [django-rest-framework-mongoengine][django-rest-framework-mongoengine] - Serializer class that supports using MongoDB as the storage layer for Django REST framework.
+* [djangorestframework-gis][djangorestframework-gis] - Geographic add-ons
+* [djangorestframework-hstore][djangorestframework-hstore] - Serializer class to support django-hstore DictionaryField model field and its schema-mode feature.
### Serializer fields
-* [drf-compound-fields](https://github.com/estebistec/drf-compound-fields) - Provides "compound" serializer fields, such as lists of simple values.
-* [django-extra-fields](https://github.com/Hipo/drf-extra-fields) - Provides extra serializer fields.
+* [drf-compound-fields][drf-compound-fields] - Provides "compound" serializer fields, such as lists of simple values.
+* [django-extra-fields][django-extra-fields] - Provides extra serializer fields.
### Views
-* [djangorestframework-bulk](https://github.com/miki725/django-rest-framework-bulk) - Implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests.
+* [djangorestframework-bulk][djangorestframework-bulk] - Implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests.
### Routers
-* [drf-nested-routers](https://github.com/alanjds/drf-nested-routers) - Provides routers and relationship fields for working with nested resources.
-* [wq.db.rest](http://wq.io/docs/about-rest) - Provides an admin-style model registration API with reasonable default URLs and viewsets.
+* [drf-nested-routers][drf-nested-routers] - Provides routers and relationship fields for working with nested resources.
+* [wq.db.rest][wq.db.rest] - Provides an admin-style model registration API with reasonable default URLs and viewsets.
### Parsers
-* [djangorestframework-msgpack](https://github.com/juanriaza/django-rest-framework-msgpack) - Provides MessagePack renderer and parser support.
-* [djangorestframework-camel-case](https://github.com/vbabiy/djangorestframework-camel-case) - Provides camel case JSON renderers and parsers.
+* [djangorestframework-msgpack][djangorestframework-msgpack] - Provides MessagePack renderer and parser support.
+* [djangorestframework-camel-case][djangorestframework-camel-case] - Provides camel case JSON renderers and parsers.
### Renderers
-* [djangorestframework-csv](https://github.com/mjumbewu/django-rest-framework-csv) - Provides CSV renderer support.
-* [drf_ujson](https://github.com/gizmag/drf-ujson-renderer) - Implements JSON rendering using the UJSON package.
-* [Django REST Pandas](https://github.com/wq/django-rest-pandas) - Pandas DataFrame-powered renderers including Excel, CSV, and SVG formats.
+* [djangorestframework-csv][djangorestframework-csv] - Provides CSV renderer support.
+* [drf_ujson][drf_ujson] - Implements JSON rendering using the UJSON package.
+* [rest-pandas][rest-pandas] - Pandas DataFrame-powered renderers including Excel, CSV, and SVG formats.
### Filtering
-* [djangorestframework-chain](https://github.com/philipn/django-rest-framework-chain) - Allows arbitrary chaining of both relations and lookup filters.
+* [djangorestframework-chain][djangorestframework-chain] - Allows arbitrary chaining of both relations and lookup filters.
### Misc
-* [djangorestrelationalhyperlink](https://github.com/fredkingham/django_rest_model_hyperlink_serializers_project) - A hyperlinked serialiser that can can be used to alter relationships via hyperlinks, but otherwise like a hyperlink model serializer.
-* [django-rest-swagger](https://github.com/marcgibbons/django-rest-swagger) - An API documentation generator for Swagger UI.
-* [django-rest-framework-proxy ](https://github.com/eofs/django-rest-framework-proxy) - Proxy to redirect incoming request to another API server.
-* [gaiarestframework](https://github.com/AppsFuel/gaiarestframework) - Utils for django-rest-framewok
-* [drf-extensions](https://github.com/chibisov/drf-extensions) - A collection of custom extensions
-* [ember-data-django-rest-adapter](https://github.com/toranb/ember-data-django-rest-adapter) - An ember-data adapter
+* [djangorestrelationalhyperlink][djangorestrelationalhyperlink] - A hyperlinked serialiser that can can be used to alter relationships via hyperlinks, but otherwise like a hyperlink model serializer.
+* [django-rest-swagger][django-rest-swagger] - An API documentation generator for Swagger UI.
+* [django-rest-framework-proxy][django-rest-framework-proxy] - Proxy to redirect incoming request to another API server.
+* [gaiarestframework][gaiarestframework] - Utils for django-rest-framewok
+* [drf-extensions][drf-extensions] - A collection of custom extensions
+* [ember-data-django-rest-adapter][ember-data-django-rest-adapter] - An ember-data adapter
+
+## Other Resources
+
+### Tutorials
+
+* [Beginner's Guide to the Django Rest Framework][beginners-guide-to-the-django-rest-framework]
+* [Getting Started with Django Rest Framework and AngularJS][getting-started-with-django-rest-framework-and-angularjs]
+* [End to end web app with Django-Rest-Framework & AngularJS][end-to-end-web-app-with-django-rest-framework-angularjs]
+* [Start Your API - django-rest-framework part 1][start-your-api-django-rest-framework-part-1]
+* [Permissions & Authentication - django-rest-framework part 2][permissions-authentication-django-rest-framework-part-2]
+* [ViewSets and Routers - django-rest-framework part 3][viewsets-and-routers-django-rest-framework-part-3]
+* [Django Rest Framework User Endpoint][django-rest-framework-user-endpoint]
+* [Check credentials using Django Rest Framework][check-credentials-using-django-rest-framework]
-## Tutorials
+### Videos
-* [Beginner's Guide to the Django Rest Framework](http://code.tutsplus.com/tutorials/beginners-guide-to-the-django-rest-framework--cms-19786)
-* [Getting Started with Django Rest Framework and AngularJS](http://blog.kevinastone.com/getting-started-with-django-rest-framework-and-angularjs.html)
-* [End to end web app with Django-Rest-Framework & AngularJS](http://blog.mourafiq.com/post/55034504632/end-to-end-web-app-with-django-rest-framework)
-* [Start Your API - django-rest-framework part 1](https://godjango.com/41-start-your-api-django-rest-framework-part-1/)
-* [Permissions & Authentication - django-rest-framework part 2](https://godjango.com/43-permissions-authentication-django-rest-framework-part-2/)
-* [ViewSets and Routers - django-rest-framework part 3](https://godjango.com/45-viewsets-and-routers-django-rest-framework-part-3/)
-* [Django Rest Framework User Endpoint](http://richardtier.com/2014/02/25/django-rest-framework-user-endpoint/)
-* [Check credentials using Django Rest Framework](http://richardtier.com/2014/03/06/110/)
+* [Ember and Django Part 1 (Video)][ember-and-django-part 1-video]
+* [Django Rest Framework Part 1 (Video)][django-rest-framework-part-1-video]
+* [Pyowa July 2013 - Django Rest Framework (Video)][pyowa-july-2013-django-rest-framework-video]
+* [django-rest-framework and angularjs (Video)][django-rest-framework-and-angularjs-video]
-## Videos
+### Articles
-* [Ember and Django Part 1 (Video)](http://www.neckbeardrepublic.com/screencasts/ember-and-django-part-1)
-* [Django Rest Framework Part 1 (Video)](http://www.neckbeardrepublic.com/screencasts/django-rest-framework-part-1)
-* [Pyowa July 2013 - Django Rest Framework (Video)](http://www.youtube.com/watch?v=E1ZrehVxpBo)
-* [django-rest-framework and angularjs (Video)](http://www.youtube.com/watch?v=Q8FRBGTJ020)
+* [Web API performance: profiling Django REST framework][web-api-performance-profiling-django-rest-framework]
+* [API Development with Django and Django REST Framework][api-development-with-django-and-django-rest-framework]
-## Articles
-* [Web API performance: profiling Django REST framework](http://dabapps.com/blog/api-performance-profiling-django-rest-framework/)
-* [API Development with Django and Django REST Framework](https://bnotions.com/api-development-with-django-and-django-rest-framework/)
+[cookiecutter]: https://github.com/jpadilla/cookiecutter-django-rest-framework
+[new-repo]: https://github.com/new
+[create-a-repo]: https://help.github.com/articles/create-a-repo/
+[travis-ci]: https://travis-ci.org
+[travis-profile]: https://travis-ci.org/profile
+[pypi-register]: https://pypi.python.org/pypi?%3Aaction=register_form
+[semver]: http://semver.org/
+[tox-docs]: https://tox.readthedocs.org/en/latest/
+[drf-compat]: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/compat.py
+[rest-framework-grid]: https://www.djangopackages.com/grids/g/django-rest-framework/
+[drf-create-pr]: https://github.com/tomchristie/django-rest-framework/compare
+[drf-create-issue]: https://github.com/tomchristie/django-rest-framework/issues/new
+[authentication]: ../api-guide/authentication.md
+[permissions]: ../api-guide/permissions.md
+[discussion-group]: https://groups.google.com/forum/#!forum/django-rest-framework
+[djangorestframework-digestauth]: https://github.com/juanriaza/django-rest-framework-digestauth
+[django-oauth-toolkit]: https://github.com/evonove/django-oauth-toolkit
+[doac]: https://github.com/Rediker-Software/doac
+[djangorestframework-jwt]: https://github.com/GetBlimp/django-rest-framework-jwt
+[hawkrest]: https://github.com/kumar303/hawkrest
+[djangorestframework-httpsignature]: https://github.com/etoccalino/django-rest-framework-httpsignature
+[djoser]: https://github.com/sunscrapers/djoser
+[drf-any-permissions]: https://github.com/kevin-brown/drf-any-permissions
+[djangorestframework-composed-permissions]: https://github.com/niwibe/djangorestframework-composed-permissions
+[rest-condition]: https://github.com/caxap/rest_condition
+[django-rest-framework-mongoengine]: https://github.com/umutbozkurt/django-rest-framework-mongoengine
+[djangorestframework-gis]: https://github.com/djangonauts/django-rest-framework-gis
+[djangorestframework-hstore]: https://github.com/djangonauts/django-rest-framework-hstore
+[drf-compound-fields]: https://github.com/estebistec/drf-compound-fields
+[django-extra-fields]: https://github.com/Hipo/drf-extra-fields
+[djangorestframework-bulk]: https://github.com/miki725/django-rest-framework-bulk
+[drf-nested-routers]: https://github.com/alanjds/drf-nested-routers
+[wq.db.rest]: http://wq.io/docs/about-rest
+[djangorestframework-msgpack]: https://github.com/juanriaza/django-rest-framework-msgpack
+[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case
+[djangorestframework-csv]: https://github.com/mjumbewu/django-rest-framework-csv
+[drf_ujson]: https://github.com/gizmag/drf-ujson-renderer
+[rest-pandas]: https://github.com/wq/django-rest-pandas
+[djangorestframework-chain]: https://github.com/philipn/django-rest-framework-chain
+[djangorestrelationalhyperlink]: https://github.com/fredkingham/django_rest_model_hyperlink_serializers_project
+[django-rest-swagger]: https://github.com/marcgibbons/django-rest-swagger
+[django-rest-framework-proxy]: https://github.com/eofs/django-rest-framework-proxy
+[gaiarestframework]: https://github.com/AppsFuel/gaiarestframework
+[drf-extensions]: https://github.com/chibisov/drf-extensions
+[ember-data-django-rest-adapter]: https://github.com/toranb/ember-data-django-rest-adapter
+[beginners-guide-to-the-django-rest-framework]: http://code.tutsplus.com/tutorials/beginners-guide-to-the-django-rest-framework--cms-19786
+[getting-started-with-django-rest-framework-and-angularjs]: http://blog.kevinastone.com/getting-started-with-django-rest-framework-and-angularjs.html
+[end-to-end-web-app-with-django-rest-framework-angularjs]: http://blog.mourafiq.com/post/55034504632/end-to-end-web-app-with-django-rest-framework
+[start-your-api-django-rest-framework-part-1]: https://godjango.com/41-start-your-api-django-rest-framework-part-1/
+[permissions-authentication-django-rest-framework-part-2]: https://godjango.com/43-permissions-authentication-django-rest-framework-part-2/
+[viewsets-and-routers-django-rest-framework-part-3]: https://godjango.com/45-viewsets-and-routers-django-rest-framework-part-3/
+[django-rest-framework-user-endpoint]: http://richardtier.com/2014/02/25/django-rest-framework-user-endpoint/
+[check-credentials-using-django-rest-framework]: http://richardtier.com/2014/03/06/110/
+[ember-and-django-part 1-video]: http://www.neckbeardrepublic.com/screencasts/ember-and-django-part-1
+[django-rest-framework-part-1-video]: http://www.neckbeardrepublic.com/screencasts/django-rest-framework-part-1
+[pyowa-july-2013-django-rest-framework-video]: http://www.youtube.com/watch?v=e1zrehvxpbo
+[django-rest-framework-and-angularjs-video]: http://www.youtube.com/watch?v=q8frbgtj020
+[web-api-performance-profiling-django-rest-framework]: http://dabapps.com/blog/api-performance-profiling-django-rest-framework/
+[api-development-with-django-and-django-rest-framework]: https://bnotions.com/api-development-with-django-and-django-rest-framework/
diff --git a/docs/topics/writable-nested-serializers.md b/docs/topics/writable-nested-serializers.md
index abc6a82f..ed614bd2 100644
--- a/docs/topics/writable-nested-serializers.md
+++ b/docs/topics/writable-nested-serializers.md
@@ -8,7 +8,7 @@ Although flat data structures serve to properly delineate between the individual
Nested data structures are easy enough to work with if they're read-only - simply nest your serializer classes and you're good to go. However, there are a few more subtleties to using writable nested serializers, due to the dependencies between the various model instances, and the need to save or delete multiple instances in a single action.
-## One-to-many data structures
+## One-to-many data structures
*Example of a **read-only** nested serializer. Nothing complex to worry about here.*
@@ -16,10 +16,10 @@ Nested data structures are easy enough to work with if they're read-only - simpl
class Meta:
model = ToDoItem
fields = ('text', 'is_completed')
-
+
class ToDoListSerializer(serializers.ModelSerializer):
items = ToDoItemSerializer(many=True, read_only=True)
-
+
class Meta:
model = ToDoList
fields = ('title', 'items')
@@ -31,7 +31,7 @@ Some example output from our serializer.
'items': {
{'text': 'Compile playlist', 'is_completed': True},
{'text': 'Send invites', 'is_completed': False},
- {'text': 'Clean house', 'is_completed': False}
+ {'text': 'Clean house', 'is_completed': False}
}
}
@@ -44,4 +44,4 @@ Let's take a look at updating our nested one-to-many data structure.
### Making PATCH requests
-[cite]: http://jsonapi.org/format/#url-based-json-api \ No newline at end of file
+[cite]: http://jsonapi.org/format/#url-based-json-api