[Python-modules-commits] [djangorestframework] 01/04: New upstream version 3.6.3
Brian May
bam at moszumanska.debian.org
Sun Jul 2 22:06:16 UTC 2017
This is an automated email from the git hooks/post-receive script.
bam pushed a commit to branch debian/master
in repository djangorestframework.
commit a69c17d0a75b8d0dfd87305313a08d32e11fda89
Author: Brian May <bam at debian.org>
Date: Mon Jul 3 07:58:18 2017 +1000
New upstream version 3.6.3
---
.travis.yml | 51 +-
CONTRIBUTING.md | 7 +-
LICENSE.md | 2 +-
PULL_REQUEST_TEMPLATE.md | 2 +-
README.md | 28 +-
codecov.yml | 7 +
docs/api-guide/authentication.md | 9 +-
docs/api-guide/exceptions.md | 56 +-
docs/api-guide/fields.md | 33 +-
docs/api-guide/filtering.md | 125 +-
docs/api-guide/generic-views.md | 9 +-
docs/api-guide/metadata.md | 12 +
docs/api-guide/pagination.md | 25 +-
docs/api-guide/parsers.md | 2 +-
docs/api-guide/permissions.md | 22 +-
docs/api-guide/relations.md | 26 +-
docs/api-guide/renderers.md | 6 +-
docs/api-guide/responses.md | 2 +-
docs/api-guide/reverse.md | 8 +-
docs/api-guide/routers.md | 22 +-
docs/api-guide/schemas.md | 223 ++-
docs/api-guide/serializers.md | 87 +-
docs/api-guide/settings.md | 44 +-
docs/api-guide/status-codes.md | 5 +
docs/api-guide/testing.md | 112 +-
docs/api-guide/throttling.md | 8 +-
docs/api-guide/validators.md | 23 +-
docs/api-guide/versioning.md | 4 +-
docs/api-guide/views.md | 14 +-
docs/api-guide/viewsets.md | 2 +
docs/img/api-docs.gif | Bin 0 -> 5616028 bytes
docs/img/api-docs.png | Bin 0 -> 161971 bytes
docs/img/books/hwa-cover.png | Bin 0 -> 30506 bytes
docs/img/books/tsd-cover.png | Bin 0 -> 118271 bytes
docs/img/django-filter.png | Bin 13678 -> 0 bytes
docs/img/premium/machinalis-readme.png | Bin 0 -> 12872 bytes
docs/img/premium/micropyramid-readme.png | Bin 0 -> 23782 bytes
docs/img/premium/rollbar-readme.png | Bin 0 -> 12367 bytes
docs/img/premium/rover-readme.png | Bin 53118 -> 53118 bytes
docs/img/premium/sentry-readme.png | Bin 24584 -> 24584 bytes
docs/img/premium/stream-readme.png | Bin 19341 -> 19341 bytes
docs/img/raml.png | Bin 0 -> 37216 bytes
docs/index.md | 47 +-
docs/topics/2.2-announcement.md | 12 +-
docs/topics/2.4-announcement.md | 6 +-
docs/topics/3.0-announcement.md | 12 +-
docs/topics/3.1-announcement.md | 2 +-
docs/topics/3.2-announcement.md | 2 +-
docs/topics/3.3-announcement.md | 2 +-
docs/topics/3.4-announcement.md | 6 +-
docs/topics/3.5-announcement.md | 266 +++
docs/topics/3.6-announcement.md | 199 ++
docs/topics/ajax-csrf-cors.md | 2 +-
docs/topics/api-clients.md | 212 +-
docs/topics/browsable-api.md | 2 -
docs/topics/browser-enhancements.md | 2 +-
docs/topics/contributing.md | 7 +-
docs/topics/documenting-your-api.md | 101 +-
docs/topics/funding.md | 76 +-
docs/topics/html-and-forms.md | 6 +-
docs/topics/internationalization.md | 4 +-
docs/topics/jobs.md | 39 +
docs/topics/kickstarter-announcement.md | 2 +-
docs/topics/project-management.md | 36 +-
docs/topics/release-notes.md | 1252 ++++++++----
...-party-resources.md => third-party-packages.md} | 76 +-
docs/topics/tutorials-and-resources.md | 116 ++
docs/tutorial/1-serialization.md | 39 +-
docs/tutorial/3-class-based-views.md | 2 +-
docs/tutorial/4-authentication-and-permissions.md | 6 +-
.../5-relationships-and-hyperlinked-apis.md | 6 +-
docs/tutorial/6-viewsets-and-routers.md | 2 +-
docs/tutorial/7-schemas-and-client-libraries.md | 57 +-
docs/tutorial/quickstart.md | 4 +-
docs_theme/404.html | 2 +-
docs_theme/css/default.css | 5 +
docs_theme/{base.html => main.html} | 22 +-
docs_theme/nav.html | 8 +-
licenses/bootstrap.md | 22 +
licenses/jquery.json-view.md | 22 +
mkdocs.yml | 8 +-
requirements/requirements-documentation.txt | 2 +-
requirements/requirements-optionals.txt | 7 +-
requirements/requirements-testing.txt | 6 +-
rest_framework/__init__.py | 6 +-
rest_framework/authtoken/models.py | 2 +-
rest_framework/authtoken/serializers.py | 9 +-
rest_framework/compat.py | 115 +-
rest_framework/decorators.py | 4 +-
rest_framework/documentation.py | 64 +
rest_framework/exceptions.py | 154 +-
rest_framework/fields.py | 184 +-
rest_framework/filters.py | 206 +-
rest_framework/generics.py | 3 +-
rest_framework/locale/da_DK/LC_MESSAGES/django.mo | Bin 529 -> 0 bytes
rest_framework/locale/da_DK/LC_MESSAGES/django.po | 439 -----
rest_framework/mixins.py | 6 +
rest_framework/negotiation.py | 2 +-
rest_framework/pagination.py | 112 +-
rest_framework/parsers.py | 15 +-
rest_framework/permissions.py | 17 +-
rest_framework/relations.py | 87 +-
rest_framework/renderers.py | 81 +-
rest_framework/request.py | 46 +-
rest_framework/response.py | 6 +-
rest_framework/reverse.py | 6 +-
rest_framework/routers.py | 141 +-
rest_framework/schemas.py | 669 +++++--
rest_framework/serializers.py | 170 +-
rest_framework/settings.py | 18 +-
.../static/rest_framework/css/bootstrap-tweaks.css | 1 -
.../static/rest_framework/css/bootstrap.min.css | 7 +-
.../static/rest_framework/docs/css/base.css | 343 ++++
.../docs/css/bootstrap-theme.min.css | 11 +
.../rest_framework/docs/css/bootstrap.min.css | 6 +
.../rest_framework/docs/css/font-awesome-4.0.3.css | 1338 +++++++++++++
.../static/rest_framework/docs/css/highlight.css | 125 ++
.../docs/css/jquery.json-view.min.css | 11 +
.../docs/fonts/fontawesome-webfont.eot | Bin 0 -> 38205 bytes
.../docs/fonts/fontawesome-webfont.svg | 414 ++++
.../docs/fonts/fontawesome-webfont.ttf | Bin 0 -> 80652 bytes
.../docs/fonts/fontawesome-webfont.woff | Bin 0 -> 44432 bytes
.../docs/fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes
.../docs/fonts/glyphicons-halflings-regular.svg | 288 +++
.../docs/fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes
.../docs/fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes
.../docs/fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes
.../static/rest_framework/docs/img/favicon.ico | Bin 0 -> 5430 bytes
.../static/rest_framework/docs/img/grid.png | Bin 0 -> 1458 bytes
.../static/rest_framework/docs/js/api.js | 314 +++
.../static/rest_framework/docs/js/bootstrap.min.js | 7 +
.../rest_framework/docs/js/highlight.pack.js | 2 +
.../rest_framework/docs/js/jquery-1.10.2.min.js | 6 +
.../rest_framework/docs/js/jquery.json-view.min.js | 7 +
.../static/rest_framework/js/bootstrap.min.js | 8 +-
.../static/rest_framework/js/coreapi-0.1.0.js | 2040 ++++++++++++++++++++
rest_framework/static/rest_framework/js/csrf.js | 2 +-
rest_framework/status.py | 6 +
rest_framework/templates/rest_framework/admin.html | 1 +
.../templates/rest_framework/admin/detail.html | 2 +-
.../templates/rest_framework/admin/dict_value.html | 11 +
.../templates/rest_framework/admin/list.html | 2 +-
rest_framework/templates/rest_framework/base.html | 13 +-
.../templates/rest_framework/docs/auth/basic.html | 38 +
.../rest_framework/docs/auth/session.html | 35 +
.../templates/rest_framework/docs/auth/token.html | 36 +
.../templates/rest_framework/docs/document.html | 30 +
.../templates/rest_framework/docs/index.html | 56 +
.../templates/rest_framework/docs/interact.html | 51 +
.../docs/langs/javascript-intro.html | 6 +
.../rest_framework/docs/langs/javascript.html | 15 +
.../rest_framework/docs/langs/python-intro.html | 3 +
.../rest_framework/docs/langs/python.html | 13 +
.../rest_framework/docs/langs/shell-intro.html | 3 +
.../templates/rest_framework/docs/langs/shell.html | 6 +
.../templates/rest_framework/docs/link.html | 102 +
.../templates/rest_framework/docs/sidebar.html | 42 +
.../horizontal/checkbox_multiple.html | 10 +-
.../templates/rest_framework/horizontal/input.html | 2 +-
.../templates/rest_framework/horizontal/radio.html | 10 +-
.../rest_framework/horizontal/select.html | 4 +-
.../rest_framework/horizontal/select_multiple.html | 4 +-
.../rest_framework/inline/checkbox_multiple.html | 6 +-
.../templates/rest_framework/inline/input.html | 2 +-
.../templates/rest_framework/inline/radio.html | 5 +-
.../templates/rest_framework/inline/select.html | 4 +-
.../rest_framework/inline/select_multiple.html | 3 +-
.../templates/rest_framework/login_base.html | 4 +-
rest_framework/templates/rest_framework/schema.js | 3 +
.../rest_framework/vertical/checkbox_multiple.html | 10 +-
.../templates/rest_framework/vertical/input.html | 2 +-
.../templates/rest_framework/vertical/radio.html | 9 +-
.../templates/rest_framework/vertical/select.html | 4 +-
.../rest_framework/vertical/select_multiple.html | 3 +-
rest_framework/templatetags/rest_framework.py | 104 +-
rest_framework/test.py | 127 +-
rest_framework/throttling.py | 7 +-
rest_framework/urlpatterns.py | 4 +-
rest_framework/utils/breadcrumbs.py | 7 +-
rest_framework/utils/encoders.py | 10 +-
rest_framework/utils/field_mapping.py | 140 +-
rest_framework/utils/formatting.py | 16 +-
rest_framework/utils/html.py | 2 +-
rest_framework/utils/mediatypes.py | 6 +-
rest_framework/utils/model_meta.py | 15 +-
rest_framework/utils/serializer_helpers.py | 15 +-
rest_framework/utils/urls.py | 4 +-
rest_framework/validators.py | 28 +-
rest_framework/versioning.py | 9 +-
rest_framework/views.py | 31 +-
rest_framework/viewsets.py | 4 +-
schema-support | 0
setup.cfg | 3 +
setup.py | 12 +-
tests/browsable_api/test_browsable_api.py | 18 +-
tests/browsable_api/test_browsable_nested_api.py | 8 +-
tests/browsable_api/test_form_rendering.py | 7 +-
tests/conftest.py | 15 +-
tests/test_api_client.py | 474 +++++
tests/test_atomic_requests.py | 46 +-
tests/test_authentication.py | 141 +-
tests/test_authtoken.py | 29 +
tests/test_bound_fields.py | 33 +
tests/test_compat.py | 67 +
tests/test_decorators.py | 30 +-
tests/test_description.py | 21 +-
tests/test_encoders.py | 94 +
tests/test_exceptions.py | 50 +-
tests/test_fields.py | 242 ++-
tests/test_filters.py | 420 ++--
tests/test_generics.py | 225 ++-
tests/test_htmlrenderer.py | 43 +-
tests/test_lazy_hyperlinks.py | 49 +
tests/test_metadata.py | 23 +-
tests/test_model_serializer.py | 157 +-
tests/test_multitable_inheritance.py | 8 +-
tests/test_negotiation.py | 69 +-
tests/test_one_to_one_with_inheritance.py | 46 +
tests/test_pagination.py | 245 ++-
tests/test_parsers.py | 80 +-
tests/test_permissions.py | 25 +-
tests/test_prefetch_related.py | 60 +
tests/test_relations.py | 29 +-
tests/test_relations_generic.py | 4 +-
tests/test_relations_hyperlink.py | 109 +-
tests/test_relations_pk.py | 120 +-
tests/test_relations_slug.py | 72 +-
tests/test_renderers.py | 215 ++-
tests/test_request.py | 46 +-
tests/test_requests_client.py | 256 +++
tests/test_reverse.py | 8 +-
tests/test_routers.py | 126 +-
tests/test_schemas.py | 407 +++-
tests/test_serializer.py | 256 ++-
tests/test_serializer_bulk_update.py | 24 +-
tests/test_serializer_lists.py | 214 ++
tests/test_serializer_nested.py | 6 +
tests/test_templatetags.py | 228 ++-
tests/test_testing.py | 103 +-
tests/test_throttling.py | 150 +-
tests/test_urlpatterns.py | 12 +-
tests/test_utils.py | 103 +-
tests/test_validation.py | 38 +-
tests/test_validation_error.py | 101 +
tests/test_validators.py | 157 +-
tests/test_versioning.py | 93 +-
tests/test_views.py | 42 +-
tests/test_viewsets.py | 19 +-
tests/test_write_only_fields.py | 6 +-
tests/utils.py | 2 +-
tox.ini | 37 +-
251 files changed, 14949 insertions(+), 3034 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index c9d9a16..7a91af8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,45 +1,50 @@
language: python
python:
+ - "2.7"
+ - "3.4"
- "3.5"
sudo: false
env:
- - TOX_ENV=py27-lint
- - TOX_ENV=py27-docs
- - TOX_ENV=py35-django19
- - TOX_ENV=py34-django19
- - TOX_ENV=py27-django19
- - TOX_ENV=py35-django18
- - TOX_ENV=py34-django18
- - TOX_ENV=py33-django18
- - TOX_ENV=py32-django18
- - TOX_ENV=py27-django18
- - TOX_ENV=py27-django110
- - TOX_ENV=py35-django110
- - TOX_ENV=py34-django110
- - TOX_ENV=py27-djangomaster
- - TOX_ENV=py34-djangomaster
- - TOX_ENV=py35-djangomaster
+ - DJANGO=1.8
+ - DJANGO=1.9
+ - DJANGO=1.10
+ - DJANGO=1.11
+ - DJANGO=master
matrix:
fast_finish: true
+ include:
+ - python: "3.6"
+ env: DJANGO=master
+ - python: "3.6"
+ env: DJANGO=1.11
+ - python: "3.3"
+ env: DJANGO=1.8
+ - python: "2.7"
+ env: TOXENV="lint"
+ - python: "2.7"
+ env: TOXENV="docs"
+ exclude:
+ - python: "2.7"
+ env: DJANGO=master
+ - python: "3.4"
+ env: DJANGO=master
+
allow_failures:
- - env: TOX_ENV=py27-djangomaster
- - env: TOX_ENV=py34-djangomaster
- - env: TOX_ENV=py35-djangomaster
+ - env: DJANGO=master
install:
- # Virtualenv < 14 is required to keep the Python 3.2 builds running.
- - pip install tox "virtualenv<14"
+ - pip install tox tox-travis
script:
- - tox -e $TOX_ENV
+ - tox
after_success:
- pip install codecov
- - codecov -e TOX_ENV
+ - codecov -e TOXENV,DJANGO
notifications:
email: false
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 03865b7..ba57956 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -50,7 +50,7 @@ Getting involved in triaging incoming issues is a good way to start contributing
To start developing on Django REST framework, clone the repo:
- git clone git at github.com:tomchristie/django-rest-framework.git
+ git clone git at github.com:encode/django-rest-framework.git
Changes should broadly follow the [PEP 8][pep-8] style conventions, and we recommend you set up your editor to automatically indicate non-conforming styles.
@@ -61,6 +61,7 @@ To run the tests, clone the repository, and then:
# Setup the virtual environment
virtualenv env
source env/bin/activate
+ pip install django
pip install -r requirements.txt
# Run the tests
@@ -197,10 +198,10 @@ If you want to draw attention to a note or warning, use a pair of enclosing line
[code-of-conduct]: https://www.djangoproject.com/conduct/
[google-group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework
[so-filter]: http://stackexchange.com/filters/66475/rest-framework
-[issues]: https://github.com/tomchristie/django-rest-framework/issues?state=open
+[issues]: https://github.com/encode/django-rest-framework/issues?state=open
[pep-8]: http://www.python.org/dev/peps/pep-0008/
[pull-requests]: https://help.github.com/articles/using-pull-requests
[tox]: https://tox.readthedocs.io/en/latest/
[markdown]: http://daringfireball.net/projects/markdown/basics
-[docs]: https://github.com/tomchristie/django-rest-framework/tree/master/docs
+[docs]: https://github.com/encode/django-rest-framework/tree/master/docs
[mou]: http://mouapp.com/
diff --git a/LICENSE.md b/LICENSE.md
index aca195e..4c599a3 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/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index 49f980c..70673c6 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -1,4 +1,4 @@
-*Note*: Before submitting this pull request, please review our [contributing guidelines](https://github.com/tomchristie/django-rest-framework/blob/master/CONTRIBUTING.md#pull-requests).
+*Note*: Before submitting this pull request, please review our [contributing guidelines](https://github.com/encode/django-rest-framework/blob/master/CONTRIBUTING.md#pull-requests).
## Description
diff --git a/README.md b/README.md
index a8e1afb..d710f3d 100644
--- a/README.md
+++ b/README.md
@@ -18,16 +18,18 @@ REST framework commercially we strongly encourage you to invest in its
continued development by **[signing up for a paid plan][funding]**.
The initial aim is to provide a single full-time position on REST framework.
-Right now we're over 58% of the way towards achieving that.
-*Every single sign-up makes a significant impact.*
+*Every single sign-up makes a significant impact towards making that possible.*
<p align="center">
- <a href="http://jobs.rover.com/"><img src="https://raw.githubusercontent.com/tomchristie/django-rest-framework/master/docs/img/premium/rover-readme.png"/></a>
- <a href="https://getsentry.com/welcome/"><img src="https://raw.githubusercontent.com/tomchristie/django-rest-framework/master/docs/img/premium/sentry-readme.png"/></a>
- <a href="https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf"><img src="https://raw.githubusercontent.com/tomchristie/django-rest-framework/master/docs/img/premium/stream-readme.png"/></a>
+ <a href="http://jobs.rover.com/"><img src="https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/rover-readme.png"/></a>
+ <a href="https://getsentry.com/welcome/"><img src="https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/sentry-readme.png"/></a>
+ <a href="https://getstream.io/try-the-api/?utm_source=drf&utm_medium=banner&utm_campaign=drf"><img src="https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/stream-readme.png"/></a>
+ <a href="https://hello.machinalis.co.uk/"><img src="https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/machinalis-readme.png"/></a>
+ <a href="https://rollbar.com/"><img src="https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/rollbar-readme.png"/></a>
+ <a href="https://micropyramid.com/django-rest-framework-development-services/"><img src="https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/micropyramid-readme.png"/></a>
</p>
-*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/), and [Stream](https://getstream.io/?utm_source=drf&utm_medium=banner&utm_campaign=drf).*
+*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/).*
---
@@ -51,8 +53,8 @@ There is a live example API for testing purposes, [available here][sandbox].
# Requirements
-* Python (2.7, 3.2, 3.3, 3.4, 3.5)
-* Django (1.8, 1.9, 1.10)
+* Python (2.7, 3.2, 3.3, 3.4, 3.5, 3.6)
+* Django (1.8, 1.9, 1.10, 1.11)
# Installation
@@ -170,14 +172,14 @@ You may also want to [follow the author on Twitter][twitter].
# Security
-If you believe you’ve found something in Django REST framework which has security implications, please **do not raise the issue in a public forum**.
+If you believe you've found something in Django REST framework which has security implications, please **do not raise the issue in a public forum**.
Send a description of the issue via email to [rest-framework-security at googlegroups.com][security-mail]. The project maintainers will then work with you to resolve any issues where required, prior to any public disclosure.
-[build-status-image]: https://secure.travis-ci.org/tomchristie/django-rest-framework.svg?branch=master
-[travis]: http://travis-ci.org/tomchristie/django-rest-framework?branch=master
-[coverage-status-image]: https://img.shields.io/codecov/c/github/tomchristie/django-rest-framework/master.svg
-[codecov]: http://codecov.io/github/tomchristie/django-rest-framework?branch=master
+[build-status-image]: https://secure.travis-ci.org/encode/django-rest-framework.svg?branch=master
+[travis]: http://travis-ci.org/encode/django-rest-framework?branch=master
+[coverage-status-image]: https://img.shields.io/codecov/c/github/encode/django-rest-framework/master.svg
+[codecov]: http://codecov.io/github/encode/django-rest-framework?branch=master
[pypi-version]: https://img.shields.io/pypi/v/djangorestframework.svg
[pypi]: https://pypi.python.org/pypi/djangorestframework
[twitter]: https://twitter.com/_tomchristie
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..d7436ab
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,7 @@
+coverage:
+ status:
+ project: false
+ patch: false
+ changes: false
+
+comment: off
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 8d880b0..2344c68 100644
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -148,7 +148,7 @@ For clients to authenticate, the token key should be included in the `Authorizat
If successfully authenticated, `TokenAuthentication` provides the following credentials.
* `request.user` will be a Django `User` instance.
-* `request.auth` will be a `rest_framework.authtoken.models.BasicToken` instance.
+* `request.auth` will be a `rest_framework.authtoken.models.Token` instance.
Unauthenticated responses that are denied permission will result in an `HTTP 401 Unauthorized` response with an appropriate WWW-Authenticate header. For example:
@@ -356,6 +356,10 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a
[Django-rest-knox][django-rest-knox] library provides models and views to handle token based authentication in a more secure and extensible way than the built-in TokenAuthentication scheme - with Single Page Applications and Mobile clients in mind. It provides per-client tokens, and views to generate them when provided some other authentication (usually basic authentication), to delete the token (providing a server enforced logout) and to delete all tokens (logs out all clients that a us [...]
+## drfpasswordless
+
+[drfpasswordless][drfpasswordless] adds (Medium, Square Cash inspired) passwordless support to Django REST Framework's own TokenAuthentication scheme. Users log in and sign up with a token sent to a contact point like an email address or a mobile number.
+
[cite]: http://jacobian.org/writing/rest-worst-practices/
[http401]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
[http403]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4
@@ -363,7 +367,7 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a
[oauth]: http://oauth.net/2/
[permission]: permissions.md
[throttling]: throttling.md
-[csrf-ajax]: https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
+[csrf-ajax]: https://docs.djangoproject.com/en/stable/ref/csrf/#ajax
[mod_wsgi_official]: http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIPassAuthorization
[django-oauth-toolkit-getting-started]: https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html
[django-rest-framework-oauth]: http://jpadilla.github.io/django-rest-framework-oauth/
@@ -396,3 +400,4 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a
[django-rest-auth]: https://github.com/Tivix/django-rest-auth
[django-rest-framework-social-oauth2]: https://github.com/PhilipGarnero/django-rest-framework-social-oauth2
[django-rest-knox]: https://github.com/James1345/django-rest-knox
+[drfpasswordless]: https://github.com/aaronn/django-rest-framework-passwordless
diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md
index 3e4b3e8..03f1622 100644
--- a/docs/api-guide/exceptions.md
+++ b/docs/api-guide/exceptions.md
@@ -47,7 +47,7 @@ Any example validation error might look like this:
You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.
-The function must take a pair of arguments, this first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a `Response` object, or return `None` if the exception cannot be handled. If the handler returns `None` then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.
+The function must take a pair of arguments, the first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a `Response` object, or return `None` if the exception cannot be handled. If the handler returns `None` then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.
For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:
@@ -98,7 +98,7 @@ Note that the exception handler will only be called for responses generated by r
The **base class** for all exceptions raised inside an `APIView` class or `@api_view`.
-To provide a custom exception, subclass `APIException` and set the `.status_code` and `.default_detail` properties on the class.
+To provide a custom exception, subclass `APIException` and set the `.status_code`, `.default_detail`, and `default_code` attributes on the class.
For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the "503 Service Unavailable" HTTP response code. You could do this like so:
@@ -107,10 +107,42 @@ For example, if your API relies on a third party service that may sometimes be u
class ServiceUnavailable(APIException):
status_code = 503
default_detail = 'Service temporarily unavailable, try again later.'
+ default_code = 'service_unavailable'
+
+#### Inspecting API exceptions
+
+There are a number of different properties available for inspecting the status
+of an API exception. You can use these to build custom exception handling
+for your project.
+
+The available attributes and methods are:
+
+* `.detail` - Return the textual description of the error.
+* `.get_codes()` - Return the code identifier of the error.
+* `.get_full_details()` - Return both the textual description and the code identifier.
+
+In most cases the error detail will be a simple item:
+
+ >>> print(exc.detail)
+ You do not have permission to perform this action.
+ >>> print(exc.get_codes())
+ permission_denied
+ >>> print(exc.get_full_details())
+ {'message':'You do not have permission to perform this action.','code':'permission_denied'}
+
+In the case of validation errors the error detail will be either a list or
+dictionary of items:
+
+ >>> print(exc.detail)
+ {"name":"This field is required.","age":"A valid integer is required."}
+ >>> print(exc.get_codes())
+ {"name":"required","age":"invalid"}
+ >>> print(exc.get_full_details())
+ {"name":{"message":"This field is required.","code":"required"},"age":{"message":"A valid integer is required.","code":"invalid"}}
## ParseError
-**Signature:** `ParseError(detail=None)`
+**Signature:** `ParseError(detail=None, code=None)`
Raised if the request contains malformed data when accessing `request.data`.
@@ -118,7 +150,7 @@ By default this exception results in a response with the HTTP status code "400 B
## AuthenticationFailed
-**Signature:** `AuthenticationFailed(detail=None)`
+**Signature:** `AuthenticationFailed(detail=None, code=None)`
Raised when an incoming request includes incorrect authentication.
@@ -126,7 +158,7 @@ By default this exception results in a response with the HTTP status code "401 U
## NotAuthenticated
-**Signature:** `NotAuthenticated(detail=None)`
+**Signature:** `NotAuthenticated(detail=None, code=None)`
Raised when an unauthenticated request fails the permission checks.
@@ -134,7 +166,7 @@ By default this exception results in a response with the HTTP status code "401 U
## PermissionDenied
-**Signature:** `PermissionDenied(detail=None)`
+**Signature:** `PermissionDenied(detail=None, code=None)`
Raised when an authenticated request fails the permission checks.
@@ -142,7 +174,7 @@ By default this exception results in a response with the HTTP status code "403 F
## NotFound
-**Signature:** `NotFound(detail=None)`
+**Signature:** `NotFound(detail=None, code=None)`
Raised when a resource does not exists at the given URL. This exception is equivalent to the standard `Http404` Django exception.
@@ -150,7 +182,7 @@ By default this exception results in a response with the HTTP status code "404 N
## MethodNotAllowed
-**Signature:** `MethodNotAllowed(method, detail=None)`
+**Signature:** `MethodNotAllowed(method, detail=None, code=None)`
Raised when an incoming request occurs that does not map to a handler method on the view.
@@ -158,7 +190,7 @@ By default this exception results in a response with the HTTP status code "405 M
## NotAcceptable
-**Signature:** `NotAcceptable(detail=None)`
+**Signature:** `NotAcceptable(detail=None, code=None)`
Raised when an incoming request occurs with an `Accept` header that cannot be satisfied by any of the available renderers.
@@ -166,7 +198,7 @@ By default this exception results in a response with the HTTP status code "406 N
## UnsupportedMediaType
-**Signature:** `UnsupportedMediaType(media_type, detail=None)`
+**Signature:** `UnsupportedMediaType(media_type, detail=None, code=None)`
Raised if there are no parsers that can handle the content type of the request data when accessing `request.data`.
@@ -174,7 +206,7 @@ By default this exception results in a response with the HTTP status code "415 U
## Throttled
-**Signature:** `Throttled(wait=None, detail=None)`
+**Signature:** `Throttled(wait=None, detail=None, code=None)`
Raised when an incoming request fails the throttling checks.
@@ -182,7 +214,7 @@ By default this exception results in a response with the HTTP status code "429 T
## ValidationError
-**Signature:** `ValidationError(detail)`
+**Signature:** `ValidationError(detail, code=None)`
The `ValidationError` exception is slightly different from the other `APIException` classes:
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index f95608a..28d06f2 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -49,10 +49,14 @@ Defaults to `False`
### `default`
-If set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behavior is to not populate the attribute at all.
+If set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behaviour is to not populate the attribute at all.
+
+The `default` is not applied during partial update operations. In the partial update case only fields that are provided in the incoming data will have a validated value returned.
May be set to a function or other callable, in which case the value will be evaluated each time it is used. When called, it will receive no arguments. If the callable has a `set_context` method, that will be called each time before getting the value with the field instance as only argument. This works the same way as for [validators](validators.md#using-set_context).
+When serializing the instance, default will be used if the the object attribute or dictionary key is not present in the instance.
+
Note that setting a `default` value implies that the field is not required. Including both the `default` and `required` keyword arguments is invalid and will raise an error.
### `source`
@@ -259,7 +263,7 @@ Corresponds to `django.db.models.fields.DecimalField`.
**Signature**: `DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)`
-- `max_digits` The maximum number of digits allowed in the number. Note that this number must be greater than or equal to decimal_places.
+- `max_digits` The maximum number of digits allowed in the number. It must be either `None` or an integer greater than or equal to `decimal_places`.
- `decimal_places` The number of decimal places to store with the number.
- `coerce_to_string` Set to `True` if string values should be returned for the representation, or `False` if `Decimal` objects should be returned. Defaults to the same value as the `COERCE_DECIMAL_TO_STRING` settings key, which will be `True` unless overridden. If `Decimal` objects are returned by the serializer, then the final output format will be determined by the renderer. Note that setting `localize` will force the value to `True`.
- `max_value` Validate that the number provided is no greater than this value.
@@ -290,9 +294,9 @@ A date and time representation.
Corresponds to `django.db.models.fields.DateTimeField`.
-**Signature:** `DateTimeField(format=None, input_formats=None)`
+**Signature:** `DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)`
-* `format` - A string representing the output format. If not specified, this defaults to the same value as the `DATETIME_FORMAT` settings key, which will be `'iso-8601'` unless set. Setting to a format string indicates that `to_representation` return values should be coerced to string output. Format strings are described below. Setting this value to `None` indicates that Python `datetime` objects should be returned by `to_representation`. In this case the datetime encoding will be deter [...]
+* `format` - A string representing the output format. If not specified, this defaults to the same value as the `DATETIME_FORMAT` settings key, which will be `'iso-8601'` unless set. Setting to a format string indicates that `to_representation` return values should be coerced to string output. Format strings are described below. Setting this value to `None` indicates that Python `datetime` objects should be returned by `to_representation`. In this case the datetime encoding will be determ [...]
* `input_formats` - A list of strings representing the input formats which may be used to parse the date. If not specified, the `DATETIME_INPUT_FORMATS` setting will be used, which defaults to `['iso-8601']`.
#### `DateTimeField` format strings.
@@ -301,8 +305,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.
@@ -321,7 +323,7 @@ A date representation.
Corresponds to `django.db.models.fields.DateField`
-**Signature:** `DateField(format=None, input_formats=None)`
+**Signature:** `DateField(format=api_settings.DATE_FORMAT, input_formats=None)`
* `format` - A string representing the output format. If not specified, this defaults to the same value as the `DATE_FORMAT` settings key, which will be `'iso-8601'` unless set. Setting to a format string indicates that `to_representation` return values should be coerced to string output. Format strings are described below. Setting this value to `None` indicates that Python `date` objects should be returned by `to_representation`. In this case the date encoding will be determined by the [...]
* `input_formats` - A list of strings representing the input formats which may be used to parse the date. If not specified, the `DATE_INPUT_FORMATS` setting will be used, which defaults to `['iso-8601']`.
@@ -336,7 +338,7 @@ A time representation.
Corresponds to `django.db.models.fields.TimeField`
-**Signature:** `TimeField(format=None, input_formats=None)`
+**Signature:** `TimeField(format=api_settings.TIME_FORMAT, input_formats=None)`
* `format` - A string representing the output format. If not specified, this defaults to the same value as the `TIME_FORMAT` settings key, which will be `'iso-8601'` unless set. Setting to a format string indicates that `to_representation` return values should be coerced to string output. Format strings are described below. Setting this value to `None` indicates that Python `time` objects should be returned by `to_representation`. In this case the time encoding will be determined by the [...]
* `input_formats` - A list of strings representing the input formats which may be used to parse the date. If not specified, the `TIME_INPUT_FORMATS` setting will be used, which defaults to `['iso-8601']`.
@@ -432,9 +434,11 @@ Requires either the `Pillow` package or `PIL` package. The `Pillow` package is
A field class that validates a list of objects.
-**Signature**: `ListField(child)`
+**Signature**: `ListField(child, min_length=None, max_length=None)`
- `child` - A field instance that should be used for validating the objects in the list. If this argument is not provided then objects in the list will not be validated.
+- `min_length` - Validates that the list contains no fewer than this number of elements.
+- `max_length` - Validates that the list contains no more than this number of elements.
For example, to validate a list of integers you might use something like the following:
@@ -486,7 +490,7 @@ This field is used by default with `ModelSerializer` when including field names
**Signature**: `ReadOnlyField()`
-For example, is `has_expired` was a property on the `Account` model, then the following serializer would automatically generate it as a `ReadOnlyField`:
+For example, if `has_expired` was a property on the `Account` model, then the following serializer would automatically generate it as a `ReadOnlyField`:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
@@ -624,7 +628,6 @@ The `.fail()` method is a shortcut for raising `ValidationError` that takes a me
def to_internal_value(self, data):
if not isinstance(data, six.text_type):
- msg = 'Incorrect type. Expected a string, but got %s'
self.fail('incorrect_type', input_type=type(data).__name__)
if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
@@ -664,12 +667,12 @@ The [django-rest-framework-gis][django-rest-framework-gis] package provides geog
The [django-rest-framework-hstore][django-rest-framework-hstore] package provides an `HStoreField` to support [django-hstore][django-hstore] `DictionaryField` model field.
-[cite]: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.cleaned_data
+[cite]: https://docs.djangoproject.com/en/stable/ref/forms/api/#django.forms.Form.cleaned_data
[html-and-forms]: ../topics/html-and-forms.md
-[FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS
+[FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS
[ecma262]: http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
-[strftime]: http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
-[django-widgets]: https://docs.djangoproject.com/en/dev/ref/forms/widgets/
+[strftime]: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
+[django-widgets]: https://docs.djangoproject.com/en/stable/ref/forms/widgets/
[iso8601]: http://www.w3.org/TR/NOTE-datetime
[drf-compound-fields]: https://drf-compound-fields.readthedocs.io
[drf-extra-fields]: https://github.com/Hipo/drf-extra-fields
diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md
index 8664dcc..58bf286 100644
--- a/docs/api-guide/filtering.md
+++ b/docs/api-guide/filtering.md
@@ -89,24 +89,24 @@ Generic filters can also present themselves as HTML controls in the browsable AP
## Setting filter backends
-The default filter backends may be set globally, using the `DEFAULT_FILTER_BACKENDS` setting. For example.
+The default filter backends may be set globally, using the `DEFAULT_FILTER_BACKENDS` setting. For example.
REST_FRAMEWORK = {
- 'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
+ 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
You can also set the filter backends on a per-view, or per-viewset basis,
using the `GenericAPIView` class-based views.
+ import django_filters.rest_framework
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
- from rest_framework import filters
from rest_framework import generics
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
- filter_backends = (filters.DjangoFilterBackend,)
+ filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
## Filtering and object lookups
@@ -139,21 +139,26 @@ Note that you can use both an overridden `.get_queryset()` and generic filtering
## DjangoFilterBackend
-The `DjangoFilterBackend` class supports highly customizable field filtering, using the [django-filter package][django-filter].
+The `django-filter` library includes a `DjangoFilterBackend` class which
+supports highly customizable field filtering for REST framework.
-To use REST framework's `DjangoFilterBackend`, first install `django-filter`.
+To use `DjangoFilterBackend`, first install `django-filter`. Then add `django_filters` to Django's `INSTALLED_APPS`
pip install django-filter
-If you are using the browsable API or admin API you may also want to install `django-crispy-forms`, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML.
+You should now either add the filter backend to your settings:
- pip install django-crispy-forms
+ REST_FRAMEWORK = {
+ 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
+ }
-With crispy forms installed and added to Django's `INSTALLED_APPS`, the browsable API will present a filtering control for `DjangoFilterBackend`, like so:
+Or add the filter backend to an individual View or ViewSet.
-![Django Filter](../img/django-filter.png)
+ from django_filters.rest_framework import DjangoFilterBackend
-#### Specifying filter fields
+ class UserListView(generics.ListAPIView):
+ ...
+ filter_backends = (DjangoFilterBackend,)
If all you need is simple equality-based filtering, you can set a `filter_fields` attribute on the view, or viewset, listing the set of fields you wish to filter against.
@@ -167,83 +172,10 @@ This will automatically create a `FilterSet` class for the given fields, and wil
http://example.com/api/products?category=clothing&in_stock=True
-#### Specifying a FilterSet
-
-For more advanced filtering requirements you can specify a `FilterSet` class that should be used by the view. For example:
-
- import django_filters
- from myapp.models import Product
- from myapp.serializers import ProductSerializer
- from rest_framework import filters
- from rest_framework import generics
-
- class ProductFilter(filters.FilterSet):
- min_price = django_filters.NumberFilter(name="price", lookup_expr='gte')
- max_price = django_filters.NumberFilter(name="price", lookup_expr='lte')
- class Meta:
- model = Product
- fields = ['category', 'in_stock', 'min_price', 'max_price']
-
- class ProductList(generics.ListAPIView):
- queryset = Product.objects.all()
- serializer_class = ProductSerializer
- filter_backends = (filters.DjangoFilterBackend,)
- filter_class = ProductFilter
-
-
-Which will allow you to make requests such as:
-
- http://example.com/api/products?category=clothing&max_price=10.00
-
-You can also span relationships using `django-filter`, let's assume that each
-product has foreign key to `Manufacturer` model, so we create filter that
-filters using `Manufacturer` name. For example:
-
- from myapp.models import Product
- from myapp.serializers import ProductSerializer
- from rest_framework import filters
- from rest_framework import generics
-
- class ProductFilter(filters.FilterSet):
- class Meta:
- model = Product
- fields = ['category', 'in_stock', 'manufacturer__name']
+For more advanced filtering requirements you can specify a `FilterSet` class that should be used by the view.
+You can read more about `FilterSet`s in the [django-filter documentation][django-filter-docs].
+It's also recommended that you read the section on [DRF integration][django-filter-drf-docs].
-This enables us to make queries like:
-
- http://example.com/api/products?manufacturer__name=foo
-
-This is nice, but it exposes the Django's double underscore convention as part of the API. If you instead want to explicitly name the filter argument you can instead explicitly include it on the `FilterSet` class:
-
- import django_filters
- from myapp.models import Product
- from myapp.serializers import ProductSerializer
- from rest_framework import filters
- from rest_framework import generics
-
- class ProductFilter(filters.FilterSet):
- manufacturer = django_filters.CharFilter(name="manufacturer__name")
-
- class Meta:
- model = Product
- fields = ['category', 'in_stock', 'manufacturer']
-
-And now you can execute:
-
- http://example.com/api/products?manufacturer=foo
-
-For more details on using filter sets see the [django-filter documentation][django-filter-docs].
-
----
-
-**Hints & Tips**
-
-* By default filtering is not enabled. If you want to use `DjangoFilterBackend` remember to make sure it is installed by using the `'DEFAULT_FILTER_BACKENDS'` setting.
-* When using boolean fields, you should use the values `True` and `False` in the URL query parameters, rather than `0`, `1`, `true` or `false`. (The allowed boolean values are currently hardwired in Django's [NullBooleanSelect implementation][nullbooleanselect].)
-* `django-filter` supports filtering across relationships, using Django's double-underscore syntax.
-* For Django 1.3 support, make sure to install `django-filter` version 0.5.4, as later versions drop support for 1.3.
-
----
## SearchFilter
@@ -417,6 +349,15 @@ Generic filters may also present an interface in the browsable API. To do so you
The method should return a rendered HTML string.
+## Pagination & schemas
+
+You can also make the filter controls available to the schema autogeneration
+that REST framework provides, by implementing a `get_schema_fields()` method. This method should have the following signature:
+
+`get_schema_fields(self, view)`
+
+The method should return a list of `coreapi.Field` instances.
+
# Third party packages
The following third party packages provide additional filter implementations.
@@ -433,14 +374,20 @@ The [djangorestframework-word-filter][django-rest-framework-word-search-filter]
[django-url-filter][django-url-filter] provides a safe way to filter data via human-friendly URLs. It works very similar to DRF serializers and fields in a sense that they can be nested except they are called filtersets and filters. That provides easy way to filter related data. Also this library is generic-purpose so it can be used to filter other sources of data and not only Django `QuerySet`s.
-[cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters
+## drf-url-filters
+
+[drf-url-filter][drf-url-filter] is a simple Django app to apply filters on drf `ModelViewSet`'s `Queryset` in a clean, simple and configurable way. It also supports validations on incoming query params and their values. A beautiful python package `Voluptuous` is being used for validations on the incoming query parameters. The best part about voluptuous is you can define your own validations as per your query params requirements.
+
+[cite]: https://docs.djangoproject.com/en/stable/topics/db/queries/#retrieving-specific-objects-with-filters
[django-filter]: https://github.com/alex/django-filter
[django-filter-docs]: https://django-filter.readthedocs.io/en/latest/index.html
+[django-filter-drf-docs]: https://django-filter.readthedocs.io/en/develop/guide/rest_framework.html
[guardian]: https://django-guardian.readthedocs.io/
[view-permissions]: https://django-guardian.readthedocs.io/en/latest/userguide/assign.html
[view-permissions-blogpost]: http://blog.nyaruka.com/adding-a-view-permission-to-django-models
[nullbooleanselect]: https://github.com/django/django/blob/master/django/forms/widgets.py
-[search-django-admin]: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields
+[search-django-admin]: https://docs.djangoproject.com/en/stable/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields
[django-rest-framework-filters]: https://github.com/philipn/django-rest-framework-filters
[django-rest-framework-word-search-filter]: https://github.com/trollknurr/django-rest-framework-word-search-filter
[django-url-filter]: https://github.com/miki725/django-url-filter
+[drf-url-filter]: https://github.com/manjitkumar/drf-url-filters
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index d7dc30c..ae27050 100644
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -69,7 +69,7 @@ The following attributes control the basic view behavior.
The following attributes are used to control pagination when used with list views.
-* `pagination_class` - The pagination class that should be used when paginating list results. Defaults to the same value as the `DEFAULT_PAGINATION_CLASS` setting, which is `'rest_framework.pagination.PageNumberPagination'`.
+* `pagination_class` - The pagination class that should be used when paginating list results. Defaults to the same value as the `DEFAULT_PAGINATION_CLASS` setting, which is `'rest_framework.pagination.PageNumberPagination'`. Setting `pagination_class=None` will disable pagination on this view.
**Filtering**:
@@ -220,8 +220,6 @@ Also provides a `.partial_update(request, *args, **kwargs)` method, which is sim
If an object is updated this returns a `200 OK` response, with a serialized representation of the object as the body of the response.
-If an object is created, for example when making a `DELETE` request followed by a `PUT` request to the same URL, this returns a `201 Created` response, with a serialized representation of the object as the body of the response.
-
If the request data provided for updating the object was invalid, a `400 Bad Request` response will be returned, with the error details as the body of the response.
## DestroyModelMixin
@@ -330,7 +328,8 @@ For example, if you need to lookup objects based on multiple fields in the URL c
queryset = self.filter_queryset(queryset) # Apply any filter backends
filter = {}
for field in self.lookup_fields:
- filter[field] = self.kwargs[field]
+ if self.kwargs[field]: # Ignore empty fields.
+ filter[field] = self.kwargs[field]
return get_object_or_404(queryset, **filter) # Lookup the object
You can then simply apply this mixin to a view or viewset anytime you need to apply the custom behavior.
@@ -383,7 +382,7 @@ The [django-rest-framework-bulk package][django-rest-framework-bulk] implements
[Django Rest Multiple Models][django-rest-multiple-models] provides a generic view (and mixin) for sending multiple serialized models and/or querysets via a single API request.
-[cite]: https://docs.djangoproject.com/en/dev/ref/class-based-views/#base-vs-generic-views
+[cite]: https://docs.djangoproject.com/en/stable/ref/class-based-views/#base-vs-generic-views
[GenericAPIView]: #genericapiview
[ListModelMixin]: #listmodelmixin
[CreateModelMixin]: #createmodelmixin
... 25779 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/djangorestframework.git
More information about the Python-modules-commits
mailing list