diff --git a/LICENSE.md b/LICENSE.md
index aca195ec4..4c599a394 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
# License
-Copyright (c) 2011-2016, Tom Christie
+Copyright (c) 2011-2017, Tom Christie
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index 609f99184..7d11aa081 100644
--- a/README.md
+++ b/README.md
@@ -26,9 +26,10 @@ The initial aim is to provide a single full-time position on REST framework.
+
-*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), and [Rollbar](https://rollbar.com).*
+*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), [Rollbar](https://rollbar.com), and [MicroPyramid](https://micropyramid.com/django-rest-framework-development-services/).*
---
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index 22ce7dd77..677598205 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -303,8 +303,6 @@ Format strings may either be [Python strftime formats][strftime] which explicitl
When a value of `None` is used for the format `datetime` objects will be returned by `to_representation` and the final output representation will determined by the renderer class.
-In the case of JSON this means the default datetime representation uses the [ECMA 262 date time string specification][ecma262]. This is a subset of ISO 8601 which uses millisecond precision, and includes the 'Z' suffix for the UTC timezone, for example: `2013-01-29T12:34:56.123Z`.
-
#### `auto_now` and `auto_now_add` model fields.
When using `ModelSerializer` or `HyperlinkedModelSerializer`, note that any model fields with `auto_now=True` or `auto_now_add=True` will use serializer fields that are `read_only=True` by default.
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index 6602d5e2c..a3f7fdcc1 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -700,7 +700,7 @@ You can override a URL field view name and lookup field by using either, or both
model = Account
fields = ('account_url', 'account_name', 'users', 'created')
extra_kwargs = {
- 'url': {'view_name': 'accounts', 'lookup_field': 'account_name'}
+ 'url': {'view_name': 'accounts', 'lookup_field': 'account_name'},
'users': {'lookup_field': 'username'}
}
@@ -1100,8 +1100,6 @@ This API included the `.get_field()`, `.get_pk_field()` and other methods.
Because the serializers have been fundamentally redesigned with 3.0 this API no longer exists. You can still modify the fields that get created but you'll need to refer to the source code, and be aware that if the changes you make are against private bits of API then they may be subject to change.
-A new interface for controlling this behavior is currently planned for REST framework 3.1.
-
---
# Third party packages
@@ -1159,6 +1157,9 @@ The [html-json-forms][html-json-forms] package provides an algorithm and seriali
[djangorestframework-queryfields][djangorestframework-queryfields] allows API clients to specify which fields will be sent in the response via inclusion/exclusion query parameters.
+## DRF Writable Nested
+
+The [drf-writable-nested][drf-writable-nested] package provides writable nested model serializer which allows to create/update models with nested related data.
[cite]: https://groups.google.com/d/topic/django-users/sVFaOfQi4wY/discussion
[relations]: relations.md
@@ -1179,3 +1180,4 @@ The [html-json-forms][html-json-forms] package provides an algorithm and seriali
[drf-base64]: https://bitbucket.org/levit_scs/drf_base64
[drf-serializer-extensions]: https://github.com/evenicoulddoit/django-rest-framework-serializer-extensions
[djangorestframework-queryfields]: http://djangorestframework-queryfields.readthedocs.io/
+[drf-writable-nested]: http://github.com/Brogency/drf-writable-nested
diff --git a/docs/img/premium/micropyramid-readme.png b/docs/img/premium/micropyramid-readme.png
new file mode 100644
index 000000000..9fa9500e1
Binary files /dev/null and b/docs/img/premium/micropyramid-readme.png differ
diff --git a/docs/index.md b/docs/index.md
index 1760ce916..4abfba587 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -76,10 +76,11 @@ The initial aim is to provide a single full-time position on REST framework.
Stream
Machinalis
Rollbar
+ MicroPyramid
-*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), and [Rollbar](https://rollbar.com).*
+*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover](http://jobs.rover.com/), [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf), [Machinalis](https://hello.machinalis.co.uk/), [Rollbar](https://rollbar.com), and [MicroPyramid](https://micropyramid.com/django-rest-framework-development-services/).*
---
@@ -237,7 +238,8 @@ General guides to using REST framework.
* [Browser enhancements][browser-enhancements]
* [The Browsable API][browsableapi]
* [REST, Hypermedia & HATEOAS][rest-hypermedia-hateoas]
-* [Third Party Resources][third-party-resources]
+* [Third Party Packages][third-party-packages]
+* [Tutorials and Resources][tutorials-and-resources]
* [Contributing to REST framework][contributing]
* [Project management][project-management]
* [3.0 Announcement][3.0-announcement]
@@ -250,6 +252,7 @@ General guides to using REST framework.
* [Mozilla Grant][mozilla-grant]
* [Funding][funding]
* [Release Notes][release-notes]
+* [Jobs][jobs]
## Development
@@ -366,7 +369,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[rest-hypermedia-hateoas]: topics/rest-hypermedia-hateoas.md
[contributing]: topics/contributing.md
[project-management]: topics/project-management.md
-[third-party-resources]: topics/third-party-resources.md
+[third-party-packages]: topics/third-party-packages.md
+[tutorials-and-resources]: topics/tutorials-and-resources.md
[3.0-announcement]: topics/3.0-announcement.md
[3.1-announcement]: topics/3.1-announcement.md
[3.2-announcement]: topics/3.2-announcement.md
@@ -377,6 +381,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[mozilla-grant]: topics/mozilla-grant.md
[funding]: topics/funding.md
[release-notes]: topics/release-notes.md
+[jobs]: topics/jobs.md
[tox]: http://testrun.org/tox/latest/
diff --git a/docs/topics/jobs.md b/docs/topics/jobs.md
new file mode 100644
index 000000000..9c67483a8
--- /dev/null
+++ b/docs/topics/jobs.md
@@ -0,0 +1,39 @@
+# Jobs
+
+Looking for a new Django REST Framework related role? On this site we provide a list of job resources that may be helpful. It's also worth checking out if any of [our sponsors are hiring][drf-funding].
+
+
+## Places to Look for Django REST Framework Jobs
+
+* [https://www.djangoproject.com/community/jobs/][djangoproject-website]
+* [https://www.python.org/jobs/][python-org-jobs]
+* [https://djangogigs.com][django-gigs-com]
+* [https://djangojobs.net/jobs/][django-jobs-net]
+* [http://djangojobbers.com][django-jobbers-com]
+* [https://www.indeed.com/q-Django-jobs.html][indeed-com]
+* [http://stackoverflow.com/jobs/developer-jobs-using-django][stackoverflow-com]
+* [https://www.upwork.com/o/jobs/browse/skill/django-framework/][upwork-com]
+* [https://www.technojobs.co.uk/django-jobs][technobjobs-co-uk]
+* [https://remoteok.io/remote-django-jobs][remoteok-io]
+* [https://www.remotepython.com/jobs/][remotepython-com]
+
+
+Know of any other great resources for Django REST Framework jobs that are missing in our list? Please [submit a pull request][submit-pr] or [email us][anna-email].
+
+Wonder how else you can help? One of the best ways you can help Django REST Framework is to ask interviewers if their company is signed up for [REST Framework sponsorship][drf-funding] yet.
+
+
+[djangoproject-website]: https://www.djangoproject.com/community/jobs/
+[python-org-jobs]: https://www.python.org/jobs/
+[django-gigs-com]: https://djangogigs.com
+[django-jobs-net]: https://djangojobs.net/jobs/
+[django-jobbers-com]: http://djangojobbers.com
+[indeed-com]: https://www.indeed.com/q-Django-jobs.html
+[stackoverflow-com]: http://stackoverflow.com/jobs/developer-jobs-using-django
+[upwork-com]: https://www.upwork.com/o/jobs/browse/skill/django-framework/
+[technobjobs-co-uk]: https://www.technojobs.co.uk/django-jobs
+[remoteok-io]: https://remoteok.io/remote-django-jobs
+[remotepython-com]: https://www.remotepython.com/jobs/
+[drf-funding]: https://fund.django-rest-framework.org/topics/funding/
+[submit-pr]: https://github.com/tomchristie/django-rest-framework
+[anna-email]: mailto:anna@django-rest-framework.org
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index af6ad7a74..085f888b7 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -40,6 +40,24 @@ You can determine your currently installed version using `pip freeze`:
## 3.5.x series
+### 3.5.4
+
+**Date**: [10th February 2017][3.5.4-milestone]
+
+* Add max_length and min_length arguments for ListField. ([#4877][gh4877])
+* Add per-view custom exception handler support. ([#4753][gh4753])
+* Support disabling of declared fields on serializer subclasses. ([#4764][gh4764])
+* Support custom view names on `@list_route` and `@detail_route` endpoints. ([#4821][gh4821])
+* Correct labels for fields in login template when custom user model is used. ([#4841][gh4841])
+* Whitespace fixes for descriptions generated from docstrings. ([#4759][gh4759], [#4869][gh4869], [#4870][gh4870])
+* Better error reporting when schemas are returned by views without a schema renderer. ([#4790][gh4790])
+* Fix for returned response of `PUT` requests when `prefetch_related` is used. ([#4661][gh4661], [#4668][gh4668])
+* Fix for breadcrumb view names. ([#4750][gh4750])
+* Fix for RequestsClient ensuring fully qualified URLs. ([#4678][gh4678])
+* Fix for incorrect behavior of writable-nested fields check in some cases. ([#4634][gh4634], [#4669][gh4669])
+* Resolve Django deprecation warnings. ([#4712][gh4712])
+* Various cleanup of test cases.
+
### 3.5.3
**Date**: [7th November 2016][3.5.3-milestone]
@@ -639,6 +657,7 @@ For older release notes, [please see the version 2.x documentation][old-release-
[3.5.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.5.1+Release%22
[3.5.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.5.2+Release%22
[3.5.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.5.3+Release%22
+[3.5.4-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.5.4+Release%22
[gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013
@@ -1216,3 +1235,22 @@ For older release notes, [please see the version 2.x documentation][old-release-
[gh4645]: https://github.com/tomchristie/django-rest-framework/issues/4645
[gh4646]: https://github.com/tomchristie/django-rest-framework/issues/4646
[gh4650]: https://github.com/tomchristie/django-rest-framework/issues/4650
+
+
+
+[gh4877]: https://github.com/tomchristie/django-rest-framework/issues/4877
+[gh4753]: https://github.com/tomchristie/django-rest-framework/issues/4753
+[gh4764]: https://github.com/tomchristie/django-rest-framework/issues/4764
+[gh4821]: https://github.com/tomchristie/django-rest-framework/issues/4821
+[gh4841]: https://github.com/tomchristie/django-rest-framework/issues/4841
+[gh4759]: https://github.com/tomchristie/django-rest-framework/issues/4759
+[gh4869]: https://github.com/tomchristie/django-rest-framework/issues/4869
+[gh4870]: https://github.com/tomchristie/django-rest-framework/issues/4870
+[gh4790]: https://github.com/tomchristie/django-rest-framework/issues/4790
+[gh4661]: https://github.com/tomchristie/django-rest-framework/issues/4661
+[gh4668]: https://github.com/tomchristie/django-rest-framework/issues/4668
+[gh4750]: https://github.com/tomchristie/django-rest-framework/issues/4750
+[gh4678]: https://github.com/tomchristie/django-rest-framework/issues/4678
+[gh4634]: https://github.com/tomchristie/django-rest-framework/issues/4634
+[gh4669]: https://github.com/tomchristie/django-rest-framework/issues/4669
+[gh4712]: https://github.com/tomchristie/django-rest-framework/issues/4712
diff --git a/docs/topics/third-party-resources.md b/docs/topics/third-party-packages.md
similarity index 85%
rename from docs/topics/third-party-resources.md
rename to docs/topics/third-party-packages.md
index 1ccedbc01..d092e163e 100644
--- a/docs/topics/third-party-resources.md
+++ b/docs/topics/third-party-packages.md
@@ -1,4 +1,4 @@
-# Third Party Resources
+# Third Party Packages
> Software ecosystems […] establish a community that further accelerates the sharing of knowledge, content, issues, expertise and skills.
>
@@ -165,7 +165,7 @@ We suggest adding your package to the [REST Framework][rest-framework-grid] grid
#### 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.
+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 Packages][third-party-packages] section.
#### Announce on the discussion group.
@@ -261,33 +261,6 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
* [django-rest-framework-version-transforms][django-rest-framework-version-transforms] - Enables the use of delta transformations for versioning of DRF resource representations.
* [django-rest-messaging][django-rest-messaging], [django-rest-messaging-centrifugo][django-rest-messaging-centrifugo] and [django-rest-messaging-js][django-rest-messaging-js] - A real-time pluggable messaging service using DRM.
-## 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]
-* [Django REST Framework course][django-rest-framework-course]
-
-### Videos
-
-* [Ember and Django Part 1 (Video)][ember-and-django-part 1-video]
-* [Django Rest Framework Part 1 (Video)][django-rest-framework-part-1-video]
-
-### Articles
-
-* [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]
-* [Blog posts about Django REST framework][medium-django-rest-framework]
-
-### Documentations
-* [Classy Django REST Framework][cdrf.co]
[cite]: http://www.software-ecosystems.com/Software_Ecosystems/Ecosystems.html
[cookiecutter]: https://github.com/jpadilla/cookiecutter-django-rest-framework
@@ -304,7 +277,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
[drf-create-issue]: https://github.com/tomchristie/django-rest-framework/issues/new
[authentication]: ../api-guide/authentication.md
[permissions]: ../api-guide/permissions.md
-[third-party-resources]: ../topics/third-party-resources/#existing-third-party-packages
+[third-party-packages]: ../topics/third-party-packages/#existing-third-party-packages
[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
@@ -337,22 +310,9 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
[gaiarestframework]: https://github.com/AppsFuel/gaiarestframework
[drf-extensions]: https://github.com/chibisov/drf-extensions
[ember-django-adapter]: https://github.com/dustinfarris/ember-django-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://mourafiq.com/2013/07/01/end-to-end-web-app-with-django-angular-1.html
-[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
-[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/
[django-rest-auth]: https://github.com/Tivix/django-rest-auth/
[django-versatileimagefield]: https://github.com/WGBH/django-versatileimagefield
[django-versatileimagefield-drf-docs]:https://django-versatileimagefield.readthedocs.io/en/latest/drf_integration.html
-[cdrf.co]:http://www.cdrf.co
[drf-tracking]: https://github.com/aschn/drf-tracking
[django-rest-framework-braces]: https://github.com/dealertrack/django-rest-framework-braces
[dry-rest-permissions]: https://github.com/Helioscene/dry-rest-permissions
@@ -366,8 +326,6 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
[django-rest-messaging]: https://github.com/raphaelgyory/django-rest-messaging
[django-rest-messaging-centrifugo]: https://github.com/raphaelgyory/django-rest-messaging-centrifugo
[django-rest-messaging-js]: https://github.com/raphaelgyory/django-rest-messaging-js
-[medium-django-rest-framework]: https://medium.com/django-rest-framework
-[django-rest-framework-course]: https://teamtreehouse.com/library/django-rest-framework
[drf_tweaks]: https://github.com/ArabellaTech/drf_tweaks
[drf-oidc-auth]: https://github.com/ByteInternet/drf-oidc-auth
[drf-serializer-extensions]: https://github.com/evenicoulddoit/django-rest-framework-serializer-extensions
diff --git a/docs/topics/tutorials-and-resources.md b/docs/topics/tutorials-and-resources.md
new file mode 100644
index 000000000..3bbe52e44
--- /dev/null
+++ b/docs/topics/tutorials-and-resources.md
@@ -0,0 +1,109 @@
+# Tutorials and Resources
+
+There are a wide range of resources available for learning and using Django REST framework. We try to keep a comprehensive list available here.
+
+## Tutorials
+
+* [Beginner's Guide to the Django REST Framework][beginners-guide-to-the-django-rest-framework]
+* [Django REST Framework - An Introduction][drf-an-intro]
+* [Django REST Framework Tutorial][drf-tutorial]
+* [Django REST Framework Course][django-rest-framework-course]
+* [Building a RESTful API with Django REST Framework][building-a-restful-api-with-drf]
+* [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]
+* [Creating a Production Ready API with Python and Django REST Framework – Part 1][creating-a-production-ready-api-with-python-and-drf-part1]
+* [Creating a Production Ready API with Python and Django REST Framework – Part 2][creating-a-production-ready-api-with-python-and-drf-part2]
+
+
+## Videos
+
+### Talks
+
+* [How to Make a Full Fledged REST API with Django OAuth Toolkit][full-fledged-rest-api-with-django-oauth-tookit]
+* [Django REST API - So Easy You Can Learn It in 25 Minutes][django-rest-api-so-easy]
+* [Tom Christie about Django Rest Framework at Django: Under The Hood][django-under-hood-2014]
+* [Django REST Framework: Schemas, Hypermedia & Client Libraries][pycon-uk-2016]
+
+
+### Tutorials
+
+
+* [Django REST Framework Part 1][django-rest-framework-part-1-video]
+* [Django REST Framework in Your PJ's!][drf-in-your-pjs]
+* [Building a REST API Using Django & Django REST Framework][building-a-rest-api-using-django-and-drf]
+* [Blog API with Django REST Framework][blog-api-with-drf]
+* [Ember and Django Part 1][ember-and-django-part 1-video]
+* [Django REST Framework Image Upload Tutorial (with AngularJS)][drf-image-upload-tutorial-with-angularjs]
+* [Django REST Framework Tutorials][drf-tutorials]
+
+
+## Articles
+
+* [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]
+* [Integrating Pandas, Django REST Framework and Bokeh][integrating-pandas-drf-and-bokeh]
+* [Controlling Uncertainty on Web Applications and APIs][controlling-uncertainty-on-web-apps-and-apis]
+* [Full Text Search in Django REST Framework with Database Backends][full-text-search-in-drf]
+* [OAuth2 Authentication with Django REST Framework and Custom Third-Party OAuth2 Backends][oauth2-authentication-with-drf]
+* [Nested Resources with Django REST Framework][nested-resources-with-drf]
+* [Image Fields with Django REST Framework][image-fields-with-drf]
+* [Chatbot Using Django REST Framework + api.ai + Slack — Part 1/3][chatbot-using-drf-part1]
+* [New Django Admin with DRF and EmberJS... What are the News?][new-django-admin-with-drf-and-emberjs]
+* [Blog posts about Django REST Framework][medium-django-rest-framework]
+
+## Books
+
+* [Hello Web App: Intermediate Concepts, Chapter 10][hello-web-app-intermediate]
+
+### Documentations
+* [Classy Django REST Framework][cdrf.co]
+* [DRF-schema-adapter][drf-schema]
+
+Want your Django REST Framework talk/tutorial/article to be added to our website? Or know of a resource that's not yet included here? Please [submit a pull request][submit-pr] or [email us][mailto:anna@django-rest-framework.org]!
+
+
+[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://mourafiq.com/2013/07/01/end-to-end-web-app-with-django-angular-1.html
+[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
+[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/
+[cdrf.co]:http://www.cdrf.co
+[medium-django-rest-framework]: https://medium.com/django-rest-framework
+[django-rest-framework-course]: https://teamtreehouse.com/library/django-rest-framework
+[pycon-uk-2016]: https://www.youtube.com/watch?v=FjmiGh7OqVg
+[django-under-hood-2014]: https://www.youtube.com/watch?v=3cSsbe-tA0E
+[integrating-pandas-drf-and-bokeh]: http://machinalis.com/blog/pandas-django-rest-framework-bokeh/
+[controlling-uncertainty-on-web-apps-and-apis]: http://machinalis.com/blog/controlling-uncertainty-on-web-applications-and-apis/
+[full-text-search-in-drf]: http://machinalis.com/blog/full-text-search-on-django-rest-framework/
+[oauth2-authentication-with-drf]: http://machinalis.com/blog/oauth2-authentication/
+[nested-resources-with-drf]: http://machinalis.com/blog/nested-resources-with-django/
+[image-fields-with-drf]: http://machinalis.com/blog/image-fields-with-django-rest-framework/
+[chatbot-using-drf-part1]: https://chatbotslife.com/chatbot-using-django-rest-framework-api-ai-slack-part-1-3-69c7e38b7b1e#.g2aceuncf
+[new-django-admin-with-drf-and-emberjs]: https://blog.levit.be/new-django-admin-with-emberjs-what-are-the-news/
+[drf-schema]: http://drf-schema-adapter.readthedocs.io/en/latest/
+[creating-a-production-ready-api-with-python-and-drf-part1]: https://www.andreagrandi.it/2016/09/28/creating-production-ready-api-python-django-rest-framework-part-1/
+[creating-a-production-ready-api-with-python-and-drf-part2]: https://www.andreagrandi.it/2016/10/01/creating-a-production-ready-api-with-python-and-django-rest-framework-part-2/
+[hello-web-app-intermediate]: https://hellowebapp.com/order/
+[django-rest-api-so-easy]: https://www.youtube.com/watch?v=cqP758k1BaQ
+[full-fledged-rest-api-with-django-oauth-tookit]: https://www.youtube.com/watch?v=M6Ud3qC2tTk
+[drf-in-your-pjs]: https://www.youtube.com/watch?v=xMtHsWa72Ww
+[building-a-rest-api-using-django-and-drf]: https://www.youtube.com/watch?v=PwssEec3IRw
+[drf-tutorials]: https://www.youtube.com/watch?v=axRCBgbOJp8&list=PLJtp8Jm8EDzjgVg9vVyIUMoGyqtegj7FH
+[drf-image-upload-tutorial-with-angularjs]: https://www.youtube.com/watch?v=hMiNTCIY7dw&list=PLUe5s-xycYk_X0vDjYBmKuIya2a2myF8O
+[blog-api-with-drf]: https://www.youtube.com/watch?v=XMu0T6L2KRQ&list=PLEsfXFp6DpzTOcOVdZF-th7BS_GYGguAS
+[drf-an-intro]: https://realpython.com/blog/python/django-rest-framework-quick-start/
+[drf-tutorial]: https://tests4geeks.com/django-rest-framework-tutorial/
+[building-a-restful-api-with-drf]: http://agiliq.com/blog/2014/12/building-a-restful-api-with-django-rest-framework/
+[submit-pr]: https://github.com/tomchristie/django-rest-framework
diff --git a/mkdocs.yml b/mkdocs.yml
index 01c59caaa..6c57618ae 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -58,7 +58,8 @@ pages:
- 'Browser Enhancements': 'topics/browser-enhancements.md'
- 'The Browsable API': 'topics/browsable-api.md'
- 'REST, Hypermedia & HATEOAS': 'topics/rest-hypermedia-hateoas.md'
- - 'Third Party Resources': 'topics/third-party-resources.md'
+ - 'Third Party Packages': 'topics/third-party-packages.md'
+ - 'Tutorials and Resources': 'topics/tutorials-and-resources.md'
- 'Contributing to REST framework': 'topics/contributing.md'
- 'Project management': 'topics/project-management.md'
- '3.0 Announcement': 'topics/3.0-announcement.md'
@@ -71,3 +72,4 @@ pages:
- 'Mozilla Grant': 'topics/mozilla-grant.md'
- 'Funding': 'topics/funding.md'
- 'Release Notes': 'topics/release-notes.md'
+ - 'Jobs': 'topics/jobs.md'
diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py
index d9aa7718c..7a5df6804 100644
--- a/rest_framework/__init__.py
+++ b/rest_framework/__init__.py
@@ -8,7 +8,7 @@ ______ _____ _____ _____ __
"""
__title__ = 'Django REST framework'
-__version__ = '3.5.3'
+__version__ = '3.5.4'
__author__ = 'Tom Christie'
__license__ = 'BSD 2-Clause'
__copyright__ = 'Copyright 2011-2016 Tom Christie'
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index f46edef1e..2efe89610 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -1446,11 +1446,11 @@ class FileField(Field):
return data
def to_representation(self, value):
- use_url = getattr(self, 'use_url', api_settings.UPLOADED_FILES_USE_URL)
-
if not value:
return None
+ use_url = getattr(self, 'use_url', api_settings.UPLOADED_FILES_USE_URL)
+
if use_url:
if not getattr(value, 'url', None):
# If the file has not been saved it may not have a URL.
diff --git a/rest_framework/request.py b/rest_framework/request.py
index b4bd2d020..9428708ed 100644
--- a/rest_framework/request.py
+++ b/rest_framework/request.py
@@ -353,10 +353,9 @@ class Request(object):
def _not_authenticated(self):
"""
- Return a three-tuple of (authenticator, user, authtoken), representing
- an unauthenticated request.
+ Set authenticator, user & authtoken representing an unauthenticated request.
- By default this will be (None, AnonymousUser, None).
+ Defaults are None, AnonymousUser & None.
"""
self._authenticator = None
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index a8f6e9df2..94c37321f 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -15,7 +15,7 @@ from __future__ import unicode_literals
import copy
import inspect
import traceback
-from collections import OrderedDict
+from collections import Mapping, OrderedDict
from django.core.exceptions import ValidationError as DjangoValidationError
from django.core.exceptions import ImproperlyConfigured
@@ -326,11 +326,11 @@ def as_serializer_error(exc):
else:
detail = exc.detail
- if isinstance(detail, dict):
+ if isinstance(detail, Mapping):
# If errors may be a dict we use the standard {key: list of values}.
# Here we ensure that all the values are *lists* of errors.
return {
- key: value if isinstance(value, (list, dict)) else [value]
+ key: value if isinstance(value, (list, Mapping)) else [value]
for key, value in detail.items()
}
elif isinstance(detail, list):
@@ -442,7 +442,7 @@ class Serializer(BaseSerializer):
"""
Dict of native values <- Dict of primitive datatypes.
"""
- if not isinstance(data, dict):
+ if not isinstance(data, Mapping):
message = self.error_messages['invalid'].format(
datatype=type(data).__name__
)
@@ -1290,6 +1290,15 @@ class ModelSerializer(Serializer):
kwargs['read_only'] = True
extra_kwargs[field_name] = kwargs
+ else:
+ # Guard against the possible misspelling `readonly_fields` (used
+ # by the Django admin and others).
+ assert not hasattr(self.Meta, 'readonly_fields'), (
+ 'Serializer `%s.%s` has field `readonly_fields`; '
+ 'the correct spelling for the option is `read_only_fields`.' %
+ (self.__class__.__module__, self.__class__.__name__)
+ )
+
return extra_kwargs
def get_uniqueness_extra_kwargs(self, field_names, declared_fields, extra_kwargs):
diff --git a/rest_framework/utils/model_meta.py b/rest_framework/utils/model_meta.py
index f8200c98f..3e3e434e6 100644
--- a/rest_framework/utils/model_meta.py
+++ b/rest_framework/utils/model_meta.py
@@ -76,12 +76,7 @@ def _get_forward_relationships(opts):
Returns an `OrderedDict` of field names to `RelationInfo`.
"""
forward_relations = OrderedDict()
- for field in [
- field for field in opts.fields
- if field.serialize and get_remote_field(field) and not (field.primary_key and field.one_to_one)
- # If the field is a OneToOneField and it's been marked as PK, then this
- # is a multi-table inheritance auto created PK ('%_ptr').
- ]:
+ for field in [field for field in opts.fields if field.serialize and get_remote_field(field)]:
forward_relations[field.name] = RelationInfo(
model_field=field,
related_model=get_related_model(field),
diff --git a/tests/test_encoders.py b/tests/test_encoders.py
index 5c6915d0c..8f8694c47 100644
--- a/tests/test_encoders.py
+++ b/tests/test_encoders.py
@@ -1,14 +1,20 @@
-from datetime import date, datetime, timedelta, tzinfo
+from datetime import date, datetime, timedelta
from decimal import Decimal
from uuid import uuid4
import pytest
from django.test import TestCase
+from django.utils.timezone import utc
from rest_framework.compat import coreapi
from rest_framework.utils.encoders import JSONEncoder
+class MockList(object):
+ def tolist(self):
+ return [1, 2, 3]
+
+
class JSONEncoderTests(TestCase):
"""
Tests the JSONEncoder method
@@ -22,7 +28,7 @@ class JSONEncoderTests(TestCase):
Tests encoding a decimal
"""
d = Decimal(3.14)
- assert d == float(d)
+ assert self.encoder.default(d) == float(d)
def test_encode_datetime(self):
"""
@@ -30,6 +36,8 @@ class JSONEncoderTests(TestCase):
"""
current_time = datetime.now()
assert self.encoder.default(current_time) == current_time.isoformat()
+ current_time_utc = current_time.replace(tzinfo=utc)
+ assert self.encoder.default(current_time_utc) == current_time.isoformat() + 'Z'
def test_encode_time(self):
"""
@@ -42,22 +50,8 @@ class JSONEncoderTests(TestCase):
"""
Tests encoding a timezone aware timestamp
"""
-
- class UTC(tzinfo):
- """
- Class extending tzinfo to mimic UTC time
- """
- def utcoffset(self, dt):
- return timedelta(0)
-
- def tzname(self, dt):
- return "UTC"
-
- def dst(self, dt):
- return timedelta(0)
-
current_time = datetime.now().time()
- current_time = current_time.replace(tzinfo=UTC())
+ current_time = current_time.replace(tzinfo=utc)
with pytest.raises(ValueError):
self.encoder.default(current_time)
@@ -91,3 +85,10 @@ class JSONEncoderTests(TestCase):
with pytest.raises(RuntimeError):
self.encoder.default(coreapi.Error())
+
+ def test_encode_object_with_tolist(self):
+ """
+ Tests encoding a object with tolist method
+ """
+ foo = MockList()
+ assert self.encoder.default(foo) == [1, 2, 3]
diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py
index b839f56ca..cfa671125 100644
--- a/tests/test_model_serializer.py
+++ b/tests/test_model_serializer.py
@@ -10,6 +10,7 @@ from __future__ import unicode_literals
import decimal
from collections import OrderedDict
+import pytest
from django.core.exceptions import ImproperlyConfigured
from django.core.validators import (
MaxValueValidator, MinLengthValidator, MinValueValidator
@@ -1064,3 +1065,18 @@ class Issue3674Test(TestCase):
child_expected = {'parent': 1, 'value': 'def'}
self.assertEqual(child_serializer.data, child_expected)
+
+
+class Issue4897TestCase(TestCase):
+ def test_should_assert_if_writing_readonly_fields(self):
+ class TestSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = OneFieldModel
+ fields = ('char_field',)
+ readonly_fields = fields
+
+ obj = OneFieldModel.objects.create(char_field='abc')
+
+ with pytest.raises(AssertionError) as cm:
+ TestSerializer(obj).fields
+ cm.match(r'readonly_fields')
diff --git a/tests/test_serializer.py b/tests/test_serializer.py
index 04fa39c0d..cd82ba3df 100644
--- a/tests/test_serializer.py
+++ b/tests/test_serializer.py
@@ -4,9 +4,10 @@ from __future__ import unicode_literals
import inspect
import pickle
import re
+import unittest
+from collections import Mapping
import pytest
-
from django.db import models
from rest_framework import fields, relations, serializers
@@ -15,6 +16,11 @@ from rest_framework.fields import Field
from .utils import MockObject
+try:
+ from collections import ChainMap
+except ImportError:
+ ChainMap = False
+
# Test serializer fields imports.
# -------------------------------
@@ -113,6 +119,31 @@ class TestSerializer:
assert not serializer.is_valid()
assert serializer.errors == {'non_field_errors': ['No data provided']}
+ @unittest.skipUnless(ChainMap, 'requires python 3.3')
+ def test_serialize_chainmap(self):
+ data = ChainMap({'char': 'abc'}, {'integer': 123})
+ serializer = self.Serializer(data=data)
+ assert serializer.is_valid()
+ assert serializer.validated_data == {'char': 'abc', 'integer': 123}
+ assert serializer.errors == {}
+
+ def test_serialize_custom_mapping(self):
+ class SinglePurposeMapping(Mapping):
+ def __getitem__(self, key):
+ return 'abc' if key == 'char' else 123
+
+ def __iter__(self):
+ yield 'char'
+ yield 'integer'
+
+ def __len__(self):
+ return 2
+
+ serializer = self.Serializer(data=SinglePurposeMapping())
+ assert serializer.is_valid()
+ assert serializer.validated_data == {'char': 'abc', 'integer': 123}
+ assert serializer.errors == {}
+
class TestValidateMethod:
def test_non_field_error_validate_method(self):
diff --git a/tox.ini b/tox.ini
index abe045e15..b1be1a83c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -26,7 +26,7 @@ deps =
django18: Django>=1.8,<1.9
django19: Django>=1.9,<1.10
django110: Django>=1.10,<1.11
- django111: Django>=1.11a1,<2.0
+ django111: Django>=1.11b1,<2.0
djangomaster: https://github.com/django/django/archive/master.tar.gz
-rrequirements/requirements-testing.txt
-rrequirements/requirements-optionals.txt