├── tests ├── __init__.py ├── schemas │ ├── __init__.py │ └── test_get_schema_view.py ├── authentication │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ └── 0001_initial.py │ └── models.py ├── browsable_api │ ├── __init__.py │ ├── no_auth_urls.py │ ├── auth_urls.py │ ├── views.py │ └── test_browsable_nested_api.py ├── generic_relations │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ └── 0001_initial.py │ ├── models.py │ └── test_generic_relations.py ├── urls.py ├── test_templates.py ├── importable │ ├── test_installed.py │ └── __init__.py ├── test_write_only_fields.py ├── test_status.py ├── test_one_to_one_with_inheritance.py ├── test_lazy_hyperlinks.py ├── test_reverse.py ├── utils.py ├── test_settings.py ├── test_prefetch_related.py ├── test_multitable_inheritance.py └── test_middleware.py ├── rest_framework ├── utils │ ├── __init__.py │ ├── urls.py │ ├── json.py │ ├── humanize_datetime.py │ ├── breadcrumbs.py │ ├── html.py │ └── encoders.py ├── management │ ├── __init__.py │ └── commands │ │ └── __init__.py ├── templatetags │ └── __init__.py ├── authtoken │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ ├── __init__.py │ │ │ └── drf_create_token.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0001_initial.py │ │ └── 0002_auto_20160226_1747.py │ ├── __init__.py │ ├── apps.py │ ├── admin.py │ ├── models.py │ ├── serializers.py │ └── views.py ├── templates │ └── rest_framework │ │ ├── inline │ │ ├── list_fieldset.html │ │ ├── form.html │ │ ├── fieldset.html │ │ ├── list_field.html │ │ ├── dict_field.html │ │ ├── checkbox.html │ │ ├── textarea.html │ │ ├── input.html │ │ ├── checkbox_multiple.html │ │ ├── radio.html │ │ ├── select.html │ │ └── select_multiple.html │ │ ├── api.html │ │ ├── login.html │ │ ├── admin │ │ ├── simple_list_value.html │ │ ├── list_value.html │ │ ├── dict_value.html │ │ ├── detail.html │ │ └── list.html │ │ ├── schema.js │ │ ├── horizontal │ │ ├── form.html │ │ ├── list_field.html │ │ ├── dict_field.html │ │ ├── list_fieldset.html │ │ ├── fieldset.html │ │ ├── checkbox.html │ │ ├── textarea.html │ │ ├── input.html │ │ ├── checkbox_multiple.html │ │ ├── select.html │ │ ├── select_multiple.html │ │ └── radio.html │ │ ├── vertical │ │ ├── form.html │ │ ├── list_field.html │ │ ├── list_fieldset.html │ │ ├── dict_field.html │ │ ├── fieldset.html │ │ ├── checkbox.html │ │ ├── textarea.html │ │ ├── input.html │ │ ├── select.html │ │ ├── checkbox_multiple.html │ │ ├── select_multiple.html │ │ └── radio.html │ │ ├── docs │ │ ├── langs │ │ │ ├── shell-intro.html │ │ │ ├── python-intro.html │ │ │ ├── javascript-intro.html │ │ │ ├── shell.html │ │ │ ├── python.html │ │ │ └── javascript.html │ │ ├── document.html │ │ ├── auth │ │ │ ├── session.html │ │ │ ├── basic.html │ │ │ └── token.html │ │ ├── interact.html │ │ ├── error.html │ │ ├── index.html │ │ └── sidebar.html │ │ ├── raw_data_form.html │ │ ├── filters │ │ ├── search.html │ │ ├── ordering.html │ │ └── base.html │ │ └── pagination │ │ ├── previous_and_next.html │ │ └── numbers.html ├── locale │ ├── ach │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── ar │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── be │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── ca │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── cs │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── da │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── de │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── el │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── en │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── es │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── et │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── fa │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── fi │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── fr │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── gl │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── hu │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── id │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── it │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── ja │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── lv │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── mk │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── nb │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── nl │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── nn │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── no │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── pl │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── pt │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── ro │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── ru │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── sk │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── sl │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── sv │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── tr │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── uk │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── vi │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── ca_ES │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── el_GR │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── en_AU │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── en_CA │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── en_US │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── fa_IR │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── fr_CA │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── gl_ES │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── he_IL │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── ko_KR │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── pt_BR │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── pt_PT │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── tr_TR │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── zh_CN │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── zh_TW │ │ └── LC_MESSAGES │ │ │ └── django.mo │ ├── zh_Hans │ │ └── LC_MESSAGES │ │ │ └── django.mo │ └── zh_Hant │ │ └── LC_MESSAGES │ │ └── django.mo ├── static │ └── rest_framework │ │ ├── img │ │ ├── grid.png │ │ ├── glyphicons-halflings.png │ │ └── glyphicons-halflings-white.png │ │ ├── docs │ │ ├── img │ │ │ ├── grid.png │ │ │ └── favicon.ico │ │ ├── css │ │ │ ├── jquery.json-view.min.css │ │ │ └── highlight.css │ │ └── js │ │ │ └── jquery.json-view.min.js │ │ ├── fonts │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── css │ │ ├── prettify.css │ │ └── default.css │ │ └── js │ │ ├── default.js │ │ └── csrf.js ├── apps.py ├── urls.py ├── checks.py ├── __init__.py ├── schemas │ ├── utils.py │ ├── __init__.py │ └── views.py ├── reverse.py └── status.py ├── docs ├── CNAME ├── img │ ├── logo.png │ ├── raml.png │ ├── admin.png │ ├── bayer.png │ ├── inline.png │ ├── rover.png │ ├── slate.png │ ├── api-docs.gif │ ├── api-docs.png │ ├── cerulean.png │ ├── drf-yasg.png │ ├── vertical.png │ ├── horizontal.png │ ├── quickstart.png │ ├── search-filter.png │ ├── sponsors │ │ ├── 2-sga.png │ │ ├── 3-aba.png │ │ ├── 3-isl.png │ │ ├── 1-cyan.png │ │ ├── 1-divio.png │ │ ├── 1-lulu.png │ │ ├── 1-potato.png │ │ ├── 2-byte.png │ │ ├── 2-crate.png │ │ ├── 2-django.png │ │ ├── 2-heroku.png │ │ ├── 2-hipo.png │ │ ├── 2-opbeat.png │ │ ├── 2-sirono.png │ │ ├── 2-vinta.png │ │ ├── 3-blimp.png │ │ ├── 3-garfo.png │ │ ├── 3-gizmag.png │ │ ├── 3-holvi.png │ │ ├── 3-phurba.png │ │ ├── 3-safari.png │ │ ├── 3-shippo.png │ │ ├── 3-tivix.png │ │ ├── 3-vzzual.png │ │ ├── 1-runscope.png │ │ ├── 2-compile.png │ │ ├── 2-cryptico.png │ │ ├── 2-hipflask.png │ │ ├── 2-laterpay.png │ │ ├── 2-nexthub.png │ │ ├── 2-rapasso.png │ │ ├── 2-wusawork.png │ │ ├── 3-aditium.png │ │ ├── 3-beefarm.png │ │ ├── 3-cantemo.gif │ │ ├── 3-nephila.png │ │ ├── 3-openeye.png │ │ ├── 3-pkgfarm.png │ │ ├── 3-teonite.png │ │ ├── 3-wildfish.png │ │ ├── 0-eventbrite.png │ │ ├── 1-kuwaitnet.png │ │ ├── 1-purplebit.png │ │ ├── 1-wiredrive.png │ │ ├── 2-koordinates.png │ │ ├── 2-prorenata.png │ │ ├── 2-pulsecode.png │ │ ├── 3-alwaysdata.png │ │ ├── 3-brightloop.png │ │ ├── 3-fluxility.png │ │ ├── 3-ipushpull.png │ │ ├── 3-makespace.png │ │ ├── 3-pathwright.png │ │ ├── 3-providenz.png │ │ ├── 3-trackmaven.png │ │ ├── 3-transcode.png │ │ ├── 1-simple-energy.png │ │ ├── 2-singing-horse.png │ │ ├── 3-ax_semantics.png │ │ ├── 3-infinite_code.png │ │ ├── 3-life_the_game.png │ │ ├── 2-lightning_kite.png │ │ ├── 2-mirus_research.png │ │ ├── 2-rheinwerk_verlag.png │ │ ├── 2-schuberg_philis.png │ │ ├── 2-security_compass.png │ │ ├── 3-crosswordtracker.png │ │ ├── 3-thermondo-gmbh.png │ │ ├── 1-vokal_interactive.png │ │ ├── 3-imt_computer_services.png │ │ └── 3-triggered_messaging.png │ ├── travis-status.png │ ├── books │ │ ├── bda-cover.png │ │ ├── dfa-cover.jpg │ │ ├── hwa-cover.png │ │ └── tsd-cover.png │ ├── corejson-format.png │ ├── cursor-pagination.png │ ├── filter-controls.png │ ├── ordering-filter.png │ ├── pages-pagination.png │ ├── self-describing.png │ ├── premium │ │ ├── esg-readme.png │ │ ├── cadre-readme.png │ │ ├── retool-readme.png │ │ ├── rollbar-readme.png │ │ ├── sentry-readme.png │ │ ├── stream-readme.png │ │ ├── kloudless-readme.png │ │ ├── lightson-readme.png │ │ └── release-history.png │ ├── labels-and-milestones.png │ └── link-header-pagination.png ├── coreapi │ └── index.md ├── topics │ └── writable-nested-serializers.md ├── api-guide │ ├── caching.md │ └── reverse.md └── community │ └── jobs.md ├── .github └── FUNDING.yml ├── requirements ├── requirements-documentation.txt ├── requirements-testing.txt ├── requirements-codestyle.txt ├── requirements-packaging.txt └── requirements-optionals.txt ├── docs_theme ├── img │ ├── grid.png │ ├── favicon.ico │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png ├── 404.html ├── js │ └── theme.js ├── css │ └── prettify.css └── nav.html ├── codecov.yml ├── .gitignore ├── MANIFEST.in ├── PULL_REQUEST_TEMPLATE.md ├── SECURITY.md ├── requirements.txt ├── setup.cfg ├── ISSUE_TEMPLATE.md ├── licenses ├── bootstrap.md └── jquery.json-view.md ├── .travis.yml ├── tox.ini └── LICENSE.md /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/schemas/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest_framework/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/authentication/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/browsable_api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest_framework/management/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/generic_relations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest_framework/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/authentication/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | www.django-rest-framework.org 2 | -------------------------------------------------------------------------------- /rest_framework/authtoken/management/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest_framework/authtoken/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest_framework/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/generic_relations/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rest_framework/authtoken/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://fund.django-rest-framework.org/topics/funding/ 2 | -------------------------------------------------------------------------------- /docs/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/logo.png -------------------------------------------------------------------------------- /docs/img/raml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/raml.png -------------------------------------------------------------------------------- /requirements/requirements-documentation.txt: -------------------------------------------------------------------------------- 1 | # MkDocs to build our documentation. 2 | mkdocs==1.0.4 3 | -------------------------------------------------------------------------------- /docs/img/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/admin.png -------------------------------------------------------------------------------- /docs/img/bayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/bayer.png -------------------------------------------------------------------------------- /docs/img/inline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/inline.png -------------------------------------------------------------------------------- /docs/img/rover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/rover.png -------------------------------------------------------------------------------- /docs/img/slate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/slate.png -------------------------------------------------------------------------------- /docs/img/api-docs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/api-docs.gif -------------------------------------------------------------------------------- /docs/img/api-docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/api-docs.png -------------------------------------------------------------------------------- /docs/img/cerulean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/cerulean.png -------------------------------------------------------------------------------- /docs/img/drf-yasg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/drf-yasg.png -------------------------------------------------------------------------------- /docs/img/vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/vertical.png -------------------------------------------------------------------------------- /rest_framework/authtoken/__init__.py: -------------------------------------------------------------------------------- 1 | default_app_config = 'rest_framework.authtoken.apps.AuthTokenConfig' 2 | -------------------------------------------------------------------------------- /docs/img/horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/horizontal.png -------------------------------------------------------------------------------- /docs/img/quickstart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/quickstart.png -------------------------------------------------------------------------------- /docs_theme/img/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs_theme/img/grid.png -------------------------------------------------------------------------------- /docs/img/search-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/search-filter.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-sga.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-sga.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-aba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-aba.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-isl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-isl.png -------------------------------------------------------------------------------- /docs/img/travis-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/travis-status.png -------------------------------------------------------------------------------- /docs_theme/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs_theme/img/favicon.ico -------------------------------------------------------------------------------- /docs/img/books/bda-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/books/bda-cover.png -------------------------------------------------------------------------------- /docs/img/books/dfa-cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/books/dfa-cover.jpg -------------------------------------------------------------------------------- /docs/img/books/hwa-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/books/hwa-cover.png -------------------------------------------------------------------------------- /docs/img/books/tsd-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/books/tsd-cover.png -------------------------------------------------------------------------------- /docs/img/corejson-format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/corejson-format.png -------------------------------------------------------------------------------- /docs/img/cursor-pagination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/cursor-pagination.png -------------------------------------------------------------------------------- /docs/img/filter-controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/filter-controls.png -------------------------------------------------------------------------------- /docs/img/ordering-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/ordering-filter.png -------------------------------------------------------------------------------- /docs/img/pages-pagination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/pages-pagination.png -------------------------------------------------------------------------------- /docs/img/self-describing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/self-describing.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-cyan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-cyan.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-divio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-divio.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-lulu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-lulu.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-potato.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-potato.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-byte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-byte.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-crate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-crate.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-django.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-django.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-heroku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-heroku.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-hipo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-hipo.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-opbeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-opbeat.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-sirono.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-sirono.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-vinta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-vinta.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-blimp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-blimp.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-garfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-garfo.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-gizmag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-gizmag.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-holvi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-holvi.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-phurba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-phurba.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-safari.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-safari.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-shippo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-shippo.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-tivix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-tivix.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-vzzual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-vzzual.png -------------------------------------------------------------------------------- /docs/img/premium/esg-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/esg-readme.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-runscope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-runscope.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-compile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-compile.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-cryptico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-cryptico.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-hipflask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-hipflask.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-laterpay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-laterpay.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-nexthub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-nexthub.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-rapasso.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-rapasso.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-wusawork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-wusawork.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-aditium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-aditium.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-beefarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-beefarm.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-cantemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-cantemo.gif -------------------------------------------------------------------------------- /docs/img/sponsors/3-nephila.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-nephila.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-openeye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-openeye.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-pkgfarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-pkgfarm.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-teonite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-teonite.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-wildfish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-wildfish.png -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/list_fieldset.html: -------------------------------------------------------------------------------- 1 | Lists are not currently supported in HTML input. 2 | -------------------------------------------------------------------------------- /docs/img/labels-and-milestones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/labels-and-milestones.png -------------------------------------------------------------------------------- /docs/img/link-header-pagination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/link-header-pagination.png -------------------------------------------------------------------------------- /docs/img/premium/cadre-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/cadre-readme.png -------------------------------------------------------------------------------- /docs/img/premium/retool-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/retool-readme.png -------------------------------------------------------------------------------- /docs/img/premium/rollbar-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/rollbar-readme.png -------------------------------------------------------------------------------- /docs/img/premium/sentry-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/sentry-readme.png -------------------------------------------------------------------------------- /docs/img/premium/stream-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/stream-readme.png -------------------------------------------------------------------------------- /docs/img/sponsors/0-eventbrite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/0-eventbrite.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-kuwaitnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-kuwaitnet.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-purplebit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-purplebit.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-wiredrive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-wiredrive.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-koordinates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-koordinates.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-prorenata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-prorenata.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-pulsecode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-pulsecode.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-alwaysdata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-alwaysdata.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-brightloop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-brightloop.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-fluxility.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-fluxility.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-ipushpull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-ipushpull.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-makespace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-makespace.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-pathwright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-pathwright.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-providenz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-providenz.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-trackmaven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-trackmaven.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-transcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-transcode.png -------------------------------------------------------------------------------- /docs/img/premium/kloudless-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/kloudless-readme.png -------------------------------------------------------------------------------- /docs/img/premium/lightson-readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/lightson-readme.png -------------------------------------------------------------------------------- /docs/img/premium/release-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/premium/release-history.png -------------------------------------------------------------------------------- /docs/img/sponsors/1-simple-energy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-simple-energy.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-singing-horse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-singing-horse.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-ax_semantics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-ax_semantics.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-infinite_code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-infinite_code.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-life_the_game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-life_the_game.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-lightning_kite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-lightning_kite.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-mirus_research.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-mirus_research.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-rheinwerk_verlag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-rheinwerk_verlag.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-schuberg_philis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-schuberg_philis.png -------------------------------------------------------------------------------- /docs/img/sponsors/2-security_compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/2-security_compass.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-crosswordtracker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-crosswordtracker.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-thermondo-gmbh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-thermondo-gmbh.png -------------------------------------------------------------------------------- /docs_theme/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs_theme/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /requirements/requirements-testing.txt: -------------------------------------------------------------------------------- 1 | # Pytest for running the tests. 2 | pytest>=5.0,<5.1 3 | pytest-django>=3.5.1,<3.6 4 | pytest-cov>=2.7.1 5 | -------------------------------------------------------------------------------- /docs/img/sponsors/1-vokal_interactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/1-vokal_interactive.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-imt_computer_services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-imt_computer_services.png -------------------------------------------------------------------------------- /docs/img/sponsors/3-triggered_messaging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs/img/sponsors/3-triggered_messaging.png -------------------------------------------------------------------------------- /docs_theme/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/docs_theme/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /rest_framework/locale/ach/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/ach/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/ar/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/ar/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/be/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/be/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/ca/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/ca/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/cs/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/cs/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/da/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/da/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/de/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/de/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/el/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/el/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/en/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/en/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/es/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/es/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/et/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/et/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/fa/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/fa/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/fi/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/fi/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/fr/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/fr/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/gl/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/gl/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/hu/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/hu/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/id/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/id/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/it/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/it/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/ja/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/ja/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/lv/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/lv/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/mk/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/mk/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/nb/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/nb/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/nl/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/nl/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/nn/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/nn/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/no/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/no/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/pl/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/pl/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/pt/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/pt/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/ro/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/ro/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/ru/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/ru/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/sk/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/sk/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/sl/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/sl/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/sv/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/sv/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/tr/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/tr/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/uk/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/uk/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/vi/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/vi/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/ca_ES/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/ca_ES/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/el_GR/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/el_GR/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/en_AU/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/en_AU/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/en_CA/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/en_CA/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/en_US/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/en_US/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/fa_IR/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/fa_IR/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/fr_CA/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/fr_CA/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/gl_ES/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/gl_ES/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/he_IL/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/he_IL/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/ko_KR/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/ko_KR/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/pt_BR/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/pt_BR/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/pt_PT/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/tr_TR/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/tr_TR/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/zh_CN/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/zh_CN/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/zh_TW/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/zh_TW/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/img/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/img/grid.png -------------------------------------------------------------------------------- /rest_framework/locale/zh_Hans/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/zh_Hans/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/locale/zh_Hant/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/locale/zh_Hant/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/docs/img/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/docs/img/grid.png -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/api.html: -------------------------------------------------------------------------------- 1 | {% extends "rest_framework/base.html" %} 2 | 3 | {# Override this template in your own templates directory to customize #} 4 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/docs/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/docs/img/favicon.ico -------------------------------------------------------------------------------- /tests/browsable_api/no_auth_urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | 3 | from .views import MockView 4 | 5 | urlpatterns = [ 6 | url(r'^$', MockView.as_view()), 7 | ] 8 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/login.html: -------------------------------------------------------------------------------- 1 | {% extends "rest_framework/login_base.html" %} 2 | 3 | {# Override this template in your own templates directory to customize #} 4 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | precision: 2 3 | round: down 4 | range: "80...100" 5 | 6 | status: 7 | project: yes 8 | patch: no 9 | changes: no 10 | 11 | comment: off 12 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/admin/simple_list_value.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | {% for item in value %}{% if not forloop.first%},{% endif %} {{item|format_value}}{% endfor %} 3 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/schema.js: -------------------------------------------------------------------------------- 1 | var codec = new window.coreapi.codecs.CoreJSONCodec() 2 | var coreJSON = window.atob('{{ schema }}') 3 | window.schema = codec.decode(coreJSON) 4 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /requirements/requirements-codestyle.txt: -------------------------------------------------------------------------------- 1 | # PEP8 code linting, which we run on all commits. 2 | flake8==3.7.8 3 | flake8-tidy-imports==3.0.0 4 | pycodestyle==2.5.0 5 | 6 | # Sort and lint imports 7 | isort==4.3.21 8 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grangier/django-rest-framework/master/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/form.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | {% for field in form %} 3 | {% if not field.read_only %} 4 | {% render_field field style=style %} 5 | {% endif %} 6 | {% endfor %} 7 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/form.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | {% for field in form %} 3 | {% if not field.read_only %} 4 | {% render_field field style=style %} 5 | {% endif %} 6 | {% endfor %} 7 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/form.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | {% for field in form %} 3 | {% if not field.read_only %} 4 | {% render_field field style=style %} 5 | {% endif %} 6 | {% endfor %} 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.db 3 | *~ 4 | .* 5 | 6 | /site/ 7 | /htmlcov/ 8 | /coverage/ 9 | /build/ 10 | /dist/ 11 | /*.egg-info/ 12 | /env/ 13 | MANIFEST 14 | coverage.* 15 | 16 | !.gitignore 17 | !.travis.yml 18 | !.isort.cfg 19 | -------------------------------------------------------------------------------- /requirements/requirements-packaging.txt: -------------------------------------------------------------------------------- 1 | # Wheel for PyPI installs. 2 | wheel==0.30.0 3 | 4 | # Twine for secured PyPI uploads. 5 | twine==1.11.0 6 | 7 | # Transifex client for managing translation resources. 8 | transifex-client==0.11 9 | -------------------------------------------------------------------------------- /rest_framework/authtoken/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | from django.utils.translation import gettext_lazy as _ 3 | 4 | 5 | class AuthTokenConfig(AppConfig): 6 | name = 'rest_framework.authtoken' 7 | verbose_name = _("Auth Token") 8 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/fieldset.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | {% for nested_field in field %} 3 | {% if not nested_field.read_only %} 4 | {% render_field nested_field style=style %} 5 | {% endif %} 6 | {% endfor %} 7 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/langs/shell-intro.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 |
{% code bash %}# Install the command line client
3 | $ pip install coreapi-cli{% endcode %}
4 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/langs/python-intro.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 |
{% code bash %}# Install the Python client library
3 | $ pip install coreapi{% endcode %}
4 | -------------------------------------------------------------------------------- /tests/browsable_api/auth_urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import include, url 2 | 3 | from .views import MockView 4 | 5 | urlpatterns = [ 6 | url(r'^$', MockView.as_view()), 7 | url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), 8 | ] 9 | -------------------------------------------------------------------------------- /requirements/requirements-optionals.txt: -------------------------------------------------------------------------------- 1 | # Optional packages which may be used with REST framework. 2 | psycopg2-binary>=2.8.2, <2.9 3 | markdown==3.1.1 4 | pygments==2.4.2 5 | django-guardian==2.1.0 6 | django-filter>=2.2.0, <2.3 7 | coreapi==2.3.1 8 | coreschema==0.0.4 9 | pyyaml>=5.1 10 | -------------------------------------------------------------------------------- /tests/authentication/models.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.db import models 3 | 4 | 5 | class CustomToken(models.Model): 6 | key = models.CharField(max_length=40, primary_key=True) 7 | user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 8 | -------------------------------------------------------------------------------- /rest_framework/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class RestFrameworkConfig(AppConfig): 5 | name = 'rest_framework' 6 | verbose_name = "Django REST framework" 7 | 8 | def ready(self): 9 | # Add System checks 10 | from .checks import pagination_system_check # NOQA 11 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/list_field.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 |

Lists are not currently supported in HTML input.

9 |
10 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/dict_field.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 |

Dictionaries are not currently supported in HTML input.

9 |
10 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/list_field.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 4 | {% endif %} 5 | 6 |

Lists are not currently supported in HTML input.

7 |
8 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/list_fieldset.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 4 | {{ field.label }} 5 | 6 | {% endif %} 7 | 8 |

Lists are not currently supported in HTML input.

9 |
10 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/dict_field.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 4 | {% endif %} 5 | 6 |

Dictionaries are not currently supported in HTML input.

7 |
8 | -------------------------------------------------------------------------------- /rest_framework/authtoken/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from rest_framework.authtoken.models import Token 4 | 5 | 6 | class TokenAdmin(admin.ModelAdmin): 7 | list_display = ('key', 'user', 'created') 8 | fields = ('user',) 9 | ordering = ('-created',) 10 | 11 | 12 | admin.site.register(Token, TokenAdmin) 13 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/admin/list_value.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 | 4 | {% for item in value %} 5 | 6 | 7 | 8 | 9 | {% endfor %} 10 | 11 |
{{ forloop.counter0 }}{{ item|format_value }}
12 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | include LICENSE.md 3 | recursive-include tests/* * 4 | recursive-include rest_framework/static *.js *.css *.png *.ico *.eot *.svg *.ttf *.woff *.woff2 5 | recursive-include rest_framework/templates *.html schema.js 6 | recursive-include rest_framework/locale *.mo 7 | global-exclude __pycache__ 8 | global-exclude *.py[co] 9 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/admin/dict_value.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 | 4 | {% for k, v in value|items %} 5 | 6 | 7 | 8 | 9 | {% endfor %} 10 | 11 |
{{ k|format_value }}{{ v|format_value }}
12 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/checkbox.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 7 |
8 |
9 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/admin/detail.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 | 4 | {% for key, value in results|items %} 5 | {% if key in details %} 6 | 7 | {% endif %} 8 | {% endfor %} 9 | 10 |
{{ key|capfirst }}{{ value|format_value }}
11 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/langs/javascript-intro.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | {% load static %} 3 |
{% code html %}
4 | 
5 | {% endcode %}
6 | -------------------------------------------------------------------------------- /docs_theme/404.html: -------------------------------------------------------------------------------- 1 | {% extends "main.html" %} 2 | 3 | {% block content %} 4 | 5 |

404

6 |

Page not found

7 |

Try the homepage, or search the documentation.

8 | 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/list_field.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 |
9 |

Lists are not currently supported in HTML input.

10 |
11 |
12 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Note*: Before submitting this pull request, please review our [contributing guidelines](https://github.com/encode/django-rest-framework/blob/master/CONTRIBUTING.md#pull-requests). 2 | 3 | ## Description 4 | 5 | Please describe your pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue. When linking to an issue, please use `refs #...` in the description of the pull request. 6 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/dict_field.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 |
9 |

Dictionaries are not currently supported in HTML input.

10 |
11 |
12 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/raw_data_form.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | {{ form.non_field_errors }} 3 | {% for field in form %} 4 |
5 | {{ field.label_tag|add_class:"col-sm-2 control-label" }} 6 |
7 | {{ field|add_class:"form-control" }} 8 | {{ field.help_text|safe }} 9 |
10 |
11 | {% endfor %} 12 | -------------------------------------------------------------------------------- /tests/urls.py: -------------------------------------------------------------------------------- 1 | """ 2 | URLConf for test suite. 3 | 4 | We need only the docs urls for DocumentationRenderer tests. 5 | """ 6 | from django.conf.urls import url 7 | 8 | from rest_framework.compat import coreapi 9 | from rest_framework.documentation import include_docs_urls 10 | 11 | if coreapi: 12 | urlpatterns = [ 13 | url(r'^docs/', include_docs_urls(title='Test Suite API')), 14 | ] 15 | else: 16 | urlpatterns = [] 17 | -------------------------------------------------------------------------------- /tests/browsable_api/views.py: -------------------------------------------------------------------------------- 1 | from rest_framework import authentication, renderers 2 | from rest_framework.response import Response 3 | from rest_framework.views import APIView 4 | 5 | 6 | class MockView(APIView): 7 | authentication_classes = (authentication.SessionAuthentication,) 8 | renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer) 9 | 10 | def get(self, request): 11 | return Response({'a': 1, 'b': 2, 'c': 3}) 12 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/textarea.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 | 9 |
10 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/fieldset.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 | {% if field.label %} 5 | 6 | {{ field.label }} 7 | 8 | {% endif %} 9 | 10 | {% for nested_field in field %} 11 | {% if not nested_field.read_only %} 12 | {% render_field nested_field style=style %} 13 | {% endif %} 14 | {% endfor %} 15 |
16 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/list_fieldset.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 | {% if field.label %} 5 |
6 | 7 | {{ field.label }} 8 | 9 |
10 | {% endif %} 11 | 12 |

Lists are not currently supported in HTML input.

13 |
14 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/langs/shell.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 |
{% code bash %}# Load the schema document
3 | $ coreapi get {{ document.url }}{% if schema_format %} --format {{ schema_format }}{% endif %}
4 | 
5 | # Interact with the API endpoint
6 | $ coreapi action {% if section_key %}{{ section_key }} {% endif %}{{ link_key|cut:"> " }}{% for field in link.fields %} -p {{ field.name }}=...{% endfor %}{% endcode %}
7 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | 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**. 6 | 7 | Send a description of the issue via email to [rest-framework-security@googlegroups.com][security-mail]. The project maintainers will then work with you to resolve any issues where required, prior to any public disclosure. 8 | 9 | [security-mail]: mailto:rest-framework-security@googlegroups.com 10 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/filters/search.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 |

{% trans "Search" %}

3 |
4 |
5 |
6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/fieldset.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 |
3 | {% if field.label %} 4 |
5 | 6 | {{ field.label }} 7 | 8 |
9 | {% endif %} 10 | 11 | {% for nested_field in field %} 12 | {% if not nested_field.read_only %} 13 | {% render_field nested_field style=style %} 14 | {% endif %} 15 | {% endfor %} 16 |
17 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/input.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 | 9 |
10 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/checkbox_multiple.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 | {% if field.label %} 5 | 6 | {% endif %} 7 | 8 | {% for key, text in field.choices|items %} 9 |
10 | 14 |
15 | {% endfor %} 16 |
17 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/pagination/previous_and_next.html: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # The base set of requirements for REST framework is actually 2 | # just Django, but for the purposes of development and testing 3 | # there are a number of packages that are useful to install. 4 | 5 | # Laying these out as separate requirements files, allows us to 6 | # only included the relevant sets when running tox, and ensures 7 | # we are only ever declaring our dependencies in one place. 8 | 9 | -r requirements/requirements-optionals.txt 10 | -r requirements/requirements-testing.txt 11 | -r requirements/requirements-documentation.txt 12 | -r requirements/requirements-codestyle.txt 13 | -r requirements/requirements-packaging.txt 14 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/filters/ordering.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | {% load i18n %} 3 |

{% trans "Ordering" %}

4 |
5 | {% for key, label in options %} 6 | {% if key == current %} 7 | 8 | {{ label }} 9 | 10 | {% else %} 11 | {{ label }} 12 | {% endif %} 13 | {% endfor %} 14 |
15 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/checkbox.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 7 |
8 | 9 | {% if field.errors %} 10 | {% for error in field.errors %} 11 | {{ error }} 12 | {% endfor %} 13 | {% endif %} 14 | 15 | {% if field.help_text %} 16 | {{ field.help_text|safe }} 17 | {% endif %} 18 |
19 | -------------------------------------------------------------------------------- /tests/test_templates.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from django.shortcuts import render 4 | 5 | 6 | def test_base_template_with_context(): 7 | context = {'request': True, 'csrf_token': 'TOKEN'} 8 | result = render({}, 'rest_framework/base.html', context=context) 9 | assert re.search(r'\bcsrfToken: "TOKEN"', result.content.decode()) 10 | 11 | 12 | def test_base_template_with_no_context(): 13 | # base.html should be renderable with no context, 14 | # so it can be easily extended. 15 | result = render({}, 'rest_framework/base.html') 16 | # note that this response will not include a valid CSRF token 17 | assert re.search(r'\bcsrfToken: ""', result.content.decode()) 18 | -------------------------------------------------------------------------------- /tests/authentication/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.db import migrations, models 3 | 4 | 5 | class Migration(migrations.Migration): 6 | 7 | initial = True 8 | 9 | dependencies = [ 10 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='CustomToken', 16 | fields=[ 17 | ('key', models.CharField(max_length=40, primary_key=True, serialize=False)), 18 | ('user', models.OneToOneField(on_delete=models.CASCADE, to=settings.AUTH_USER_MODEL)), 19 | ], 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/filters/base.html: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /rest_framework/urls.py: -------------------------------------------------------------------------------- 1 | """ 2 | Login and logout views for the browsable API. 3 | 4 | Add these to your root URLconf if you're using the browsable API and 5 | your API requires authentication: 6 | 7 | urlpatterns = [ 8 | ... 9 | url(r'^auth/', include('rest_framework.urls')) 10 | ] 11 | 12 | You should make sure your authentication settings include `SessionAuthentication`. 13 | """ 14 | from django.conf.urls import url 15 | from django.contrib.auth import views 16 | 17 | app_name = 'rest_framework' 18 | urlpatterns = [ 19 | url(r'^login/$', views.LoginView.as_view(template_name='rest_framework/login.html'), name='login'), 20 | url(r'^logout/$', views.LogoutView.as_view(), name='logout'), 21 | ] 22 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | license_file = LICENSE.md 3 | 4 | [tool:pytest] 5 | addopts=--tb=short --strict -ra 6 | testspath = tests 7 | 8 | [flake8] 9 | ignore = E501,W504 10 | banned-modules = json = use from rest_framework.utils import json! 11 | 12 | [isort] 13 | skip=.tox 14 | atomic=true 15 | multi_line_output=5 16 | known_standard_library=types 17 | known_third_party=pytest,_pytest,django,pytz,uritemplate 18 | known_first_party=rest_framework,tests 19 | 20 | [coverage:run] 21 | # NOTE: source is ignored with pytest-cov (but uses the same). 22 | source = . 23 | include = rest_framework/*,tests/* 24 | branch = 1 25 | 26 | [coverage:report] 27 | include = rest_framework/*,tests/* 28 | exclude_lines = 29 | pragma: no cover 30 | raise NotImplementedError 31 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/langs/python.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 |
{% code python %}import coreapi
 3 | 
 4 | # Initialize a client & load the schema document
 5 | client = coreapi.Client()
 6 | schema = client.get("{{ document.url }}"{% if schema_format %}, format="{{ schema_format }}"{% endif %})
 7 | 
 8 | # Interact with the API endpoint
 9 | action = [{% if section_key %}"{{ section_key }}", {% endif %}"{{ link_key }}"]
10 | {% if link.fields %}params = {
11 | {% for field in link.fields %}    "{{ field.name }}": ...{% if not loop.last %},{% endif %}
12 | {% endfor %}}
13 | {% endif %}result = client.action(schema, action{% if link.fields %}, params=params{% endif %}){% endcode %}
14 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/checkbox.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 |
9 | 10 | 11 | {% if field.errors %} 12 | {% for error in field.errors %} 13 | {{ error }} 14 | {% endfor %} 15 | {% endif %} 16 | 17 | {% if field.help_text %} 18 | {{ field.help_text|safe }} 19 | {% endif %} 20 |
21 |
22 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/textarea.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 | 9 | 10 | {% if field.errors %} 11 | {% for error in field.errors %}{{ error }}{% endfor %} 12 | {% endif %} 13 | 14 | {% if field.help_text %} 15 | {{ field.help_text|safe }} 16 | {% endif %} 17 |
18 | -------------------------------------------------------------------------------- /tests/importable/test_installed.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | from tests import importable 4 | 5 | 6 | def test_installed(): 7 | # ensure the test app hasn't been removed from the test suite 8 | assert 'tests.importable' in settings.INSTALLED_APPS 9 | 10 | 11 | def test_compat(): 12 | assert hasattr(importable, 'compat') 13 | 14 | 15 | def test_serializer_fields_initialization(): 16 | assert hasattr(importable, 'ExampleSerializer') 17 | 18 | serializer = importable.ExampleSerializer() 19 | assert 'charfield' in serializer.fields 20 | assert 'integerfield' in serializer.fields 21 | assert 'floatfield' in serializer.fields 22 | assert 'decimalfield' in serializer.fields 23 | assert 'durationfield' in serializer.fields 24 | assert 'listfield' in serializer.fields 25 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/langs/javascript.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 |
{% code javascript %}var coreapi = window.coreapi  // Loaded by `coreapi.js`
 3 | var schema = window.schema    // Loaded by `schema.js`
 4 | 
 5 | // Initialize a client
 6 | var client = new coreapi.Client()
 7 | 
 8 | // Interact with the API endpoint
 9 | var action = [{% if section_key %}"{{ section_key }}", {% endif %}"{{ link_key }}"]
10 | {% if link.fields %}var params = {
11 | {% for field in link.fields %}    {{ field.name }}: ...{% if not loop.last %},{% endif %}
12 | {% endfor %}}
13 | {% endif %}client.action(schema, action{% if link.fields %}, params{% endif %}).then(function(result) {
14 |     // Return value is in 'result'
15 | }){% endcode %}
16 | -------------------------------------------------------------------------------- /tests/importable/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This test "app" exists to ensure that parts of Django REST Framework can be 3 | imported/invoked before Django itself has been fully initialized. 4 | """ 5 | 6 | from rest_framework import compat, serializers # noqa 7 | 8 | 9 | # test initializing fields with lazy translations 10 | class ExampleSerializer(serializers.Serializer): 11 | charfield = serializers.CharField(min_length=1, max_length=2) 12 | integerfield = serializers.IntegerField(min_value=1, max_value=2) 13 | floatfield = serializers.FloatField(min_value=1, max_value=2) 14 | decimalfield = serializers.DecimalField(max_digits=10, decimal_places=1, min_value=1, max_value=2) 15 | durationfield = serializers.DurationField(min_value=1, max_value=2) 16 | listfield = serializers.ListField(min_length=1, max_length=2) 17 | -------------------------------------------------------------------------------- /rest_framework/authtoken/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.db import migrations, models 3 | 4 | 5 | class Migration(migrations.Migration): 6 | 7 | dependencies = [ 8 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 9 | ] 10 | 11 | operations = [ 12 | migrations.CreateModel( 13 | name='Token', 14 | fields=[ 15 | ('key', models.CharField(primary_key=True, serialize=False, max_length=40)), 16 | ('created', models.DateTimeField(auto_now_add=True)), 17 | ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, related_name='auth_token', on_delete=models.CASCADE)), 18 | ], 19 | options={ 20 | }, 21 | bases=(models.Model,), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/input.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 4 | {% endif %} 5 | 6 | 7 | 8 | {% if field.errors %} 9 | {% for error in field.errors %} 10 | {{ error }} 11 | {% endfor %} 12 | {% endif %} 13 | 14 | {% if field.help_text %} 15 | {{ field.help_text|safe }} 16 | {% endif %} 17 |
18 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/textarea.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 |
9 | 10 | 11 | {% if field.errors %} 12 | {% for error in field.errors %} 13 | {{ error }} 14 | {% endfor %} 15 | {% endif %} 16 | 17 | {% if field.help_text %} 18 | {{ field.help_text|safe }} 19 | {% endif %} 20 |
21 |
22 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Checklist 2 | 3 | - [ ] I have verified that that issue exists against the `master` branch of Django REST framework. 4 | - [ ] I have searched for similar issues in both open and closed tickets and cannot find a duplicate. 5 | - [ ] This is not a usage question. (Those should be directed to the [discussion group](https://groups.google.com/forum/#!forum/django-rest-framework) instead.) 6 | - [ ] This cannot be dealt with as a third party library. (We prefer new functionality to be [in the form of third party libraries](https://www.django-rest-framework.org/community/third-party-packages/#about-third-party-packages) where possible.) 7 | - [ ] I have reduced the issue to the simplest possible case. 8 | - [ ] I have included a failing test as a pull request. (If you are unable to do so we can still accept the issue.) 9 | 10 | ## Steps to reproduce 11 | 12 | ## Expected behavior 13 | 14 | ## Actual behavior 15 | -------------------------------------------------------------------------------- /docs_theme/js/theme.js: -------------------------------------------------------------------------------- 1 | var getSearchTerm = function() { 2 | var sPageURL = window.location.search.substring(1); 3 | var sURLVariables = sPageURL.split('&'); 4 | for (var i = 0; i < sURLVariables.length; i++) { 5 | var sParameterName = sURLVariables[i].split('='); 6 | if (sParameterName[0] === 'q') { 7 | return sParameterName[1]; 8 | } 9 | } 10 | }; 11 | 12 | $(function() { 13 | var searchTerm = getSearchTerm(), 14 | $searchModal = $('#mkdocs_search_modal'), 15 | $searchQuery = $searchModal.find('#mkdocs-search-query'), 16 | $searchResults = $searchModal.find('#mkdocs-search-results'); 17 | 18 | $('pre code').parent().addClass('prettyprint well'); 19 | 20 | if (searchTerm) { 21 | $searchQuery.val(searchTerm); 22 | $searchResults.text('Searching...'); 23 | $searchModal.modal(); 24 | } 25 | 26 | $searchModal.on('shown', function() { 27 | $searchQuery.focus(); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /docs_theme/css/prettify.css: -------------------------------------------------------------------------------- 1 | .com { color: #93a1a1; } 2 | .lit { color: #195f91; } 3 | .pun, .opn, .clo { color: #93a1a1; } 4 | .fun { color: #dc322f; } 5 | .str, .atv { color: #D14; } 6 | .kwd, .prettyprint .tag { color: #1e347b; } 7 | .typ, .atn, .dec, .var { color: teal; } 8 | .pln { color: #48484c; } 9 | 10 | .prettyprint { 11 | padding: 8px; 12 | background-color: #f7f7f9; 13 | border: 1px solid #e1e1e8; 14 | } 15 | .prettyprint.linenums { 16 | -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; 17 | -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; 18 | box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; 19 | } 20 | 21 | /* Specify class=linenums on a pre to get line numbering */ 22 | ol.linenums { 23 | margin: 0 0 0 33px; /* IE indents via margin-left */ 24 | } 25 | ol.linenums li { 26 | padding-left: 12px; 27 | color: #bebec5; 28 | line-height: 20px; 29 | text-shadow: 0 1px 0 #fff; 30 | } -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/radio.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load rest_framework %} 3 | {% trans "None" as none_choice %} 4 | 5 |
6 | {% if field.label %} 7 | 10 | {% endif %} 11 | 12 | {% if field.allow_null or field.allow_blank %} 13 |
14 | 18 |
19 | {% endif %} 20 | 21 | {% for key, text in field.choices|items %} 22 |
23 | 27 |
28 | {% endfor %} 29 |
30 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/admin/list.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 | 4 | {% for column in columns%}{% endfor %} 5 | 6 | 7 | {% for row in results %} 8 | 9 | {% for key, value in row|items %} 10 | {% if key in columns %} 11 | 14 | {% endif %} 15 | {% endfor %} 16 | 23 | 24 | {% endfor %} 25 | 26 |
{{ column|capfirst }}
12 | {{ value|format_value }} 13 | 17 | {% if row.url %} 18 | 19 | {% else %} 20 | 21 | {% endif %} 22 |
27 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/css/prettify.css: -------------------------------------------------------------------------------- 1 | .com { color: #93a1a1; } 2 | .lit { color: #195f91; } 3 | .pun, .opn, .clo { color: #93a1a1; } 4 | .fun { color: #dc322f; } 5 | .str, .atv { color: #D14; } 6 | .kwd, .prettyprint .tag { color: #1e347b; } 7 | .typ, .atn, .dec, .var { color: teal; } 8 | .pln { color: #48484c; } 9 | 10 | .prettyprint { 11 | padding: 8px; 12 | background-color: #f7f7f9; 13 | border: 1px solid #e1e1e8; 14 | } 15 | .prettyprint.linenums { 16 | -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; 17 | -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; 18 | box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0; 19 | } 20 | 21 | /* Specify class=linenums on a pre to get line numbering */ 22 | ol.linenums { 23 | margin: 0 0 0 33px; /* IE indents via margin-left */ 24 | } 25 | ol.linenums li { 26 | padding-left: 12px; 27 | color: #bebec5; 28 | line-height: 20px; 29 | text-shadow: 0 1px 0 #fff; 30 | } -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/input.html: -------------------------------------------------------------------------------- 1 |
2 | {% if field.label %} 3 | 6 | {% endif %} 7 | 8 |
9 | 10 | 11 | {% if field.errors %} 12 | {% for error in field.errors %} 13 | {{ error }} 14 | {% endfor %} 15 | {% endif %} 16 | 17 | {% if field.help_text %} 18 | {{ field.help_text|safe }} 19 | {% endif %} 20 |
21 |
22 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/select.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 | {% if field.label %} 5 | 8 | {% endif %} 9 | 10 | 24 |
25 | -------------------------------------------------------------------------------- /tests/test_write_only_fields.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | from rest_framework import serializers 4 | 5 | 6 | class WriteOnlyFieldTests(TestCase): 7 | def setUp(self): 8 | class ExampleSerializer(serializers.Serializer): 9 | email = serializers.EmailField() 10 | password = serializers.CharField(write_only=True) 11 | 12 | self.Serializer = ExampleSerializer 13 | 14 | def test_write_only_fields_are_present_on_input(self): 15 | data = { 16 | 'email': 'foo@example.com', 17 | 'password': '123' 18 | } 19 | serializer = self.Serializer(data=data) 20 | assert serializer.is_valid() 21 | assert serializer.validated_data == data 22 | 23 | def test_write_only_fields_are_not_present_on_output(self): 24 | instance = { 25 | 'email': 'foo@example.com', 26 | 'password': '123' 27 | } 28 | serializer = self.Serializer(instance) 29 | assert serializer.data == {'email': 'foo@example.com'} 30 | -------------------------------------------------------------------------------- /rest_framework/checks.py: -------------------------------------------------------------------------------- 1 | from django.core.checks import Tags, Warning, register 2 | 3 | 4 | @register(Tags.compatibility) 5 | def pagination_system_check(app_configs, **kwargs): 6 | errors = [] 7 | # Use of default page size setting requires a default Paginator class 8 | from rest_framework.settings import api_settings 9 | if api_settings.PAGE_SIZE and not api_settings.DEFAULT_PAGINATION_CLASS: 10 | errors.append( 11 | Warning( 12 | "You have specified a default PAGE_SIZE pagination rest_framework setting, " 13 | "without specifying also a DEFAULT_PAGINATION_CLASS.", 14 | hint="The default for DEFAULT_PAGINATION_CLASS is None. " 15 | "In previous versions this was PageNumberPagination. " 16 | "If you wish to define PAGE_SIZE globally whilst defining " 17 | "pagination_class on a per-view basis you may silence this check.", 18 | id="rest_framework.W001" 19 | ) 20 | ) 21 | return errors 22 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/inline/select_multiple.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load rest_framework %} 3 | {% trans "No items to select." as no_items %} 4 | 5 |
6 | {% if field.label %} 7 | 10 | {% endif %} 11 | 12 | 25 |
26 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/document.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 |
5 |

{{ document.title }}

6 | {% if document.description %} 7 |

{% render_markdown document.description %}

8 | {% endif %} 9 |
10 |
11 | {% for html in lang_intro_htmls %} 12 | {% include html %} 13 | {% endfor %} 14 |
15 |
16 | {% if document|data %} 17 | {% for section_key, section in document|data|items %} 18 | {% if section_key %} 19 |

{{ section_key }} 20 |

21 | {% endif %} 22 | 23 | {% for link_key, link in section|schema_links|items %} 24 | {% include "rest_framework/docs/link.html" %} 25 | {% endfor %} 26 | {% endfor %} 27 | 28 | {% for link_key, link in document.links|items %} 29 | {% include "rest_framework/docs/link.html" %} 30 | {% endfor %} 31 | {% endif %} 32 | -------------------------------------------------------------------------------- /tests/schemas/test_get_schema_view.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from django.test import TestCase, override_settings 3 | 4 | from rest_framework import renderers 5 | from rest_framework.schemas import coreapi, get_schema_view, openapi 6 | 7 | 8 | class GetSchemaViewTests(TestCase): 9 | """For the get_schema_view() helper.""" 10 | def test_openapi(self): 11 | schema_view = get_schema_view(title="With OpenAPI") 12 | assert isinstance(schema_view.initkwargs['schema_generator'], openapi.SchemaGenerator) 13 | assert renderers.OpenAPIRenderer in schema_view.cls().renderer_classes 14 | 15 | @pytest.mark.skipif(not coreapi.coreapi, reason='coreapi is not installed') 16 | def test_coreapi(self): 17 | with override_settings(REST_FRAMEWORK={'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema'}): 18 | schema_view = get_schema_view(title="With CoreAPI") 19 | assert isinstance(schema_view.initkwargs['schema_generator'], coreapi.SchemaGenerator) 20 | assert renderers.CoreAPIOpenAPIRenderer in schema_view.cls().renderer_classes 21 | -------------------------------------------------------------------------------- /rest_framework/__init__.py: -------------------------------------------------------------------------------- 1 | r""" 2 | ______ _____ _____ _____ __ 3 | | ___ \ ___/ ___|_ _| / _| | | 4 | | |_/ / |__ \ `--. | | | |_ _ __ __ _ _ __ ___ _____ _____ _ __| |__ 5 | | /| __| `--. \ | | | _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ / 6 | | |\ \| |___/\__/ / | | | | | | | (_| | | | | | | __/\ V V / (_) | | | < 7 | \_| \_\____/\____/ \_/ |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_| 8 | """ 9 | 10 | __title__ = 'Django REST framework' 11 | __version__ = '3.11.0' 12 | __author__ = 'Tom Christie' 13 | __license__ = 'BSD 3-Clause' 14 | __copyright__ = 'Copyright 2011-2019 Encode OSS Ltd' 15 | 16 | # Version synonym 17 | VERSION = __version__ 18 | 19 | # Header encoding (see RFC5987) 20 | HTTP_HEADER_ENCODING = 'iso-8859-1' 21 | 22 | # Default datetime input and output formats 23 | ISO_8601 = 'iso-8601' 24 | 25 | default_app_config = 'rest_framework.apps.RestFrameworkConfig' 26 | 27 | 28 | class RemovedInDRF313Warning(DeprecationWarning): 29 | pass 30 | 31 | 32 | class RemovedInDRF314Warning(PendingDeprecationWarning): 33 | pass 34 | -------------------------------------------------------------------------------- /rest_framework/authtoken/migrations/0002_auto_20160226_1747.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.db import migrations, models 3 | 4 | 5 | class Migration(migrations.Migration): 6 | 7 | dependencies = [ 8 | ('authtoken', '0001_initial'), 9 | ] 10 | 11 | operations = [ 12 | migrations.AlterModelOptions( 13 | name='token', 14 | options={'verbose_name_plural': 'Tokens', 'verbose_name': 'Token'}, 15 | ), 16 | migrations.AlterField( 17 | model_name='token', 18 | name='created', 19 | field=models.DateTimeField(verbose_name='Created', auto_now_add=True), 20 | ), 21 | migrations.AlterField( 22 | model_name='token', 23 | name='key', 24 | field=models.CharField(verbose_name='Key', max_length=40, primary_key=True, serialize=False), 25 | ), 26 | migrations.AlterField( 27 | model_name='token', 28 | name='user', 29 | field=models.OneToOneField(to=settings.AUTH_USER_MODEL, verbose_name='User', related_name='auth_token', on_delete=models.CASCADE), 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /rest_framework/utils/urls.py: -------------------------------------------------------------------------------- 1 | from urllib import parse 2 | 3 | from django.utils.encoding import force_str 4 | 5 | 6 | def replace_query_param(url, key, val): 7 | """ 8 | Given a URL and a key/val pair, set or replace an item in the query 9 | parameters of the URL, and return the new URL. 10 | """ 11 | (scheme, netloc, path, query, fragment) = parse.urlsplit(force_str(url)) 12 | query_dict = parse.parse_qs(query, keep_blank_values=True) 13 | query_dict[force_str(key)] = [force_str(val)] 14 | query = parse.urlencode(sorted(list(query_dict.items())), doseq=True) 15 | return parse.urlunsplit((scheme, netloc, path, query, fragment)) 16 | 17 | 18 | def remove_query_param(url, key): 19 | """ 20 | Given a URL and a key/val pair, remove an item in the query 21 | parameters of the URL, and return the new URL. 22 | """ 23 | (scheme, netloc, path, query, fragment) = parse.urlsplit(force_str(url)) 24 | query_dict = parse.parse_qs(query, keep_blank_values=True) 25 | query_dict.pop(key, None) 26 | query = parse.urlencode(sorted(list(query_dict.items())), doseq=True) 27 | return parse.urlunsplit((scheme, netloc, path, query, fragment)) 28 | -------------------------------------------------------------------------------- /licenses/bootstrap.md: -------------------------------------------------------------------------------- 1 | https://github.com/twbs/bootstrap/ 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2011-2016 Twitter, Inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | -------------------------------------------------------------------------------- /rest_framework/utils/json.py: -------------------------------------------------------------------------------- 1 | """ 2 | Wrapper for the builtin json module that ensures compliance with the JSON spec. 3 | 4 | REST framework should always import this wrapper module in order to maintain 5 | spec-compliant encoding/decoding. Support for non-standard features should be 6 | handled by users at the renderer and parser layer. 7 | """ 8 | import functools 9 | import json # noqa 10 | 11 | 12 | def strict_constant(o): 13 | raise ValueError('Out of range float values are not JSON compliant: ' + repr(o)) 14 | 15 | 16 | @functools.wraps(json.dump) 17 | def dump(*args, **kwargs): 18 | kwargs.setdefault('allow_nan', False) 19 | return json.dump(*args, **kwargs) 20 | 21 | 22 | @functools.wraps(json.dumps) 23 | def dumps(*args, **kwargs): 24 | kwargs.setdefault('allow_nan', False) 25 | return json.dumps(*args, **kwargs) 26 | 27 | 28 | @functools.wraps(json.load) 29 | def load(*args, **kwargs): 30 | kwargs.setdefault('parse_constant', strict_constant) 31 | return json.load(*args, **kwargs) 32 | 33 | 34 | @functools.wraps(json.loads) 35 | def loads(*args, **kwargs): 36 | kwargs.setdefault('parse_constant', strict_constant) 37 | return json.loads(*args, **kwargs) 38 | -------------------------------------------------------------------------------- /tests/generic_relations/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.contenttypes.fields import ( 2 | GenericForeignKey, GenericRelation 3 | ) 4 | from django.contrib.contenttypes.models import ContentType 5 | from django.db import models 6 | 7 | 8 | class Tag(models.Model): 9 | """ 10 | Tags have a descriptive slug, and are attached to an arbitrary object. 11 | """ 12 | tag = models.SlugField() 13 | content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 14 | object_id = models.PositiveIntegerField() 15 | tagged_item = GenericForeignKey('content_type', 'object_id') 16 | 17 | def __str__(self): 18 | return self.tag 19 | 20 | 21 | class Bookmark(models.Model): 22 | """ 23 | A URL bookmark that may have multiple tags attached. 24 | """ 25 | url = models.URLField() 26 | tags = GenericRelation(Tag) 27 | 28 | def __str__(self): 29 | return 'Bookmark: %s' % self.url 30 | 31 | 32 | class Note(models.Model): 33 | """ 34 | A textual note that may have multiple tags attached. 35 | """ 36 | text = models.TextField() 37 | tags = GenericRelation(Tag) 38 | 39 | def __str__(self): 40 | return 'Note: %s' % self.text 41 | -------------------------------------------------------------------------------- /licenses/jquery.json-view.md: -------------------------------------------------------------------------------- 1 | https://github.com/bazh/jquery.json-view/ 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2014 bazh. (https://github.com/bazh) 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | the Software, and to permit persons to whom the Software is furnished to do so, 12 | subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /tests/test_status.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | from rest_framework.status import ( 4 | is_client_error, is_informational, is_redirect, is_server_error, 5 | is_success 6 | ) 7 | 8 | 9 | class TestStatus(TestCase): 10 | def test_status_categories(self): 11 | self.assertFalse(is_informational(99)) 12 | self.assertTrue(is_informational(100)) 13 | self.assertTrue(is_informational(199)) 14 | self.assertFalse(is_informational(200)) 15 | 16 | self.assertFalse(is_success(199)) 17 | self.assertTrue(is_success(200)) 18 | self.assertTrue(is_success(299)) 19 | self.assertFalse(is_success(300)) 20 | 21 | self.assertFalse(is_redirect(299)) 22 | self.assertTrue(is_redirect(300)) 23 | self.assertTrue(is_redirect(399)) 24 | self.assertFalse(is_redirect(400)) 25 | 26 | self.assertFalse(is_client_error(399)) 27 | self.assertTrue(is_client_error(400)) 28 | self.assertTrue(is_client_error(499)) 29 | self.assertFalse(is_client_error(500)) 30 | 31 | self.assertFalse(is_server_error(499)) 32 | self.assertTrue(is_server_error(500)) 33 | self.assertTrue(is_server_error(599)) 34 | self.assertFalse(is_server_error(600)) 35 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | cache: pip 3 | dist: xenial 4 | matrix: 5 | fast_finish: true 6 | include: 7 | 8 | - { python: "3.5", env: DJANGO=2.2 } 9 | 10 | - { python: "3.6", env: DJANGO=2.2 } 11 | - { python: "3.6", env: DJANGO=3.0 } 12 | - { python: "3.6", env: DJANGO=master } 13 | 14 | - { python: "3.7", env: DJANGO=2.2 } 15 | - { python: "3.7", env: DJANGO=3.0 } 16 | - { python: "3.7", env: DJANGO=master } 17 | 18 | - { python: "3.8", env: DJANGO=3.0 } 19 | - { python: "3.8", env: DJANGO=master } 20 | 21 | - { python: "3.8", env: TOXENV=base } 22 | - { python: "3.8", env: TOXENV=lint } 23 | - { python: "3.8", env: TOXENV=docs } 24 | 25 | - python: "3.8" 26 | env: TOXENV=dist 27 | script: 28 | - python setup.py bdist_wheel 29 | - rm -r djangorestframework.egg-info # see #6139 30 | - tox --installpkg ./dist/djangorestframework-*.whl 31 | - tox # test sdist 32 | 33 | allow_failures: 34 | - env: DJANGO=master 35 | 36 | install: 37 | - pip install tox tox-venv tox-travis 38 | 39 | script: 40 | - tox 41 | 42 | after_success: 43 | - pip install codecov 44 | - codecov -e TOXENV,DJANGO 45 | 46 | notifications: 47 | email: false 48 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/auth/session.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 | 4 | 36 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/select.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 | {% if field.label %} 5 | 8 | {% endif %} 9 | 10 | 24 | 25 | {% if field.errors %} 26 | {% for error in field.errors %} 27 | {{ error }} 28 | {% endfor %} 29 | {% endif %} 30 | 31 | {% if field.help_text %} 32 | {{ field.help_text|safe }} 33 | {% endif %} 34 |
35 | -------------------------------------------------------------------------------- /tests/generic_relations/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | from django.db import migrations, models 2 | 3 | 4 | class Migration(migrations.Migration): 5 | 6 | initial = True 7 | 8 | dependencies = [ 9 | ('contenttypes', '0002_remove_content_type_name'), 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='Bookmark', 15 | fields=[ 16 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 17 | ('url', models.URLField()), 18 | ], 19 | ), 20 | migrations.CreateModel( 21 | name='Note', 22 | fields=[ 23 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 24 | ('text', models.TextField()), 25 | ], 26 | ), 27 | migrations.CreateModel( 28 | name='Tag', 29 | fields=[ 30 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 31 | ('tag', models.SlugField()), 32 | ('object_id', models.PositiveIntegerField()), 33 | ('content_type', models.ForeignKey(on_delete=models.CASCADE, to='contenttypes.ContentType')), 34 | ], 35 | ), 36 | ] 37 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/checkbox_multiple.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 | {% if field.label %} 5 | 6 | {% endif %} 7 | 8 | {% if style.inline %} 9 |
10 | {% for key, text in field.choices|items %} 11 | 15 | {% endfor %} 16 |
17 | {% else %} 18 | {% for key, text in field.choices|items %} 19 |
20 | 24 |
25 | {% endfor %} 26 | {% endif %} 27 | 28 | {% if field.errors %} 29 | {% for error in field.errors %} 30 | {{ error }} 31 | {% endfor %} 32 | {% endif %} 33 | 34 | {% if field.help_text %} 35 | {{ field.help_text|safe }} 36 | {% endif %} 37 |
38 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/select_multiple.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load rest_framework %} 3 | {% trans "No items to select." as no_items %} 4 | 5 |
6 | {% if field.label %} 7 | 10 | {% endif %} 11 | 12 | 25 | 26 | {% if field.errors %} 27 | {% for error in field.errors %}{{ error }}{% endfor %} 28 | {% endif %} 29 | 30 | {% if field.help_text %} 31 | {{ field.help_text|safe }} 32 | {% endif %} 33 |
34 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/docs/css/jquery.json-view.min.css: -------------------------------------------------------------------------------- 1 | .json-view{position:relative} 2 | .json-view .collapser{width:20px;height:18px;display:block;position:absolute;left:-1.7em;top:-.2em;z-index:5;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD1JREFUeNpiYGBgOADE%2F3Hgw0DM4IRHgSsDFOzFInmMAQnY49ONzZRjDFiADT7dMLALiE8y4AGW6LoBAgwAuIkf%2F%2FB7O9sAAAAASUVORK5CYII%3D);background-repeat:no-repeat;background-position:center center;opacity:.5;cursor:pointer} 3 | .json-view .collapsed{-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-khtml-transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)} 4 | .json-view .bl{display:block;padding-left:20px;margin-left:-20px;position:relative} 5 | .json-view{font-family:monospace} 6 | .json-view ul{list-style-type:none;padding-left:2em;border-left:1px dotted;margin:.3em} 7 | .json-view ul li{position:relative} 8 | .json-view .comments,.json-view .dots{display:none;-moz-user-select:none;-ms-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none} 9 | .json-view .comments{padding-left:.8em;font-style:italic;color:#888} 10 | .json-view .bool,.json-view .null,.json-view .num,.json-view .undef{font-weight:700;color:#1A01CC} 11 | .json-view .str{color:#800} -------------------------------------------------------------------------------- /rest_framework/authtoken/models.py: -------------------------------------------------------------------------------- 1 | import binascii 2 | import os 3 | 4 | from django.conf import settings 5 | from django.db import models 6 | from django.utils.translation import gettext_lazy as _ 7 | 8 | 9 | class Token(models.Model): 10 | """ 11 | The default authorization token model. 12 | """ 13 | key = models.CharField(_("Key"), max_length=40, primary_key=True) 14 | user = models.OneToOneField( 15 | settings.AUTH_USER_MODEL, related_name='auth_token', 16 | on_delete=models.CASCADE, verbose_name=_("User") 17 | ) 18 | created = models.DateTimeField(_("Created"), auto_now_add=True) 19 | 20 | class Meta: 21 | # Work around for a bug in Django: 22 | # https://code.djangoproject.com/ticket/19422 23 | # 24 | # Also see corresponding ticket: 25 | # https://github.com/encode/django-rest-framework/issues/705 26 | abstract = 'rest_framework.authtoken' not in settings.INSTALLED_APPS 27 | verbose_name = _("Token") 28 | verbose_name_plural = _("Tokens") 29 | 30 | def save(self, *args, **kwargs): 31 | if not self.key: 32 | self.key = self.generate_key() 33 | return super().save(*args, **kwargs) 34 | 35 | def generate_key(self): 36 | return binascii.hexlify(os.urandom(20)).decode() 37 | 38 | def __str__(self): 39 | return self.key 40 | -------------------------------------------------------------------------------- /rest_framework/schemas/utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | utils.py # Shared helper functions 3 | 4 | See schemas.__init__.py for package overview. 5 | """ 6 | from django.db import models 7 | from django.utils.translation import gettext_lazy as _ 8 | 9 | from rest_framework.mixins import RetrieveModelMixin 10 | 11 | 12 | def is_list_view(path, method, view): 13 | """ 14 | Return True if the given path/method appears to represent a list view. 15 | """ 16 | if hasattr(view, 'action'): 17 | # Viewsets have an explicitly defined action, which we can inspect. 18 | return view.action == 'list' 19 | 20 | if method.lower() != 'get': 21 | return False 22 | if isinstance(view, RetrieveModelMixin): 23 | return False 24 | path_components = path.strip('/').split('/') 25 | if path_components and '{' in path_components[-1]: 26 | return False 27 | return True 28 | 29 | 30 | def get_pk_description(model, model_field): 31 | if isinstance(model_field, models.AutoField): 32 | value_type = _('unique integer value') 33 | elif isinstance(model_field, models.UUIDField): 34 | value_type = _('UUID string') 35 | else: 36 | value_type = _('unique value') 37 | 38 | return _('A {value_type} identifying this {name}.').format( 39 | value_type=value_type, 40 | name=model._meta.verbose_name, 41 | ) 42 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/checkbox_multiple.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 | {% if field.label %} 5 | 8 | {% endif %} 9 | 10 |
11 | {% if style.inline %} 12 | {% for key, text in field.choices|items %} 13 | 17 | {% endfor %} 18 | {% else %} 19 | {% for key, text in field.choices|items %} 20 |
21 | 25 |
26 | {% endfor %} 27 | {% endif %} 28 | 29 | {% if field.errors %} 30 | {% for error in field.errors %} 31 | {{ error }} 32 | {% endfor %} 33 | {% endif %} 34 | 35 | {% if field.help_text %} 36 | {{ field.help_text|safe }} 37 | {% endif %} 38 |
39 |
40 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/select.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 |
4 | {% if field.label %} 5 | 8 | {% endif %} 9 | 10 |
11 | 25 | 26 | {% if field.errors %} 27 | {% for error in field.errors %} 28 | {{ error }} 29 | {% endfor %} 30 | {% endif %} 31 | 32 | {% if field.help_text %} 33 | {{ field.help_text|safe }} 34 | {% endif %} 35 |
36 |
37 | -------------------------------------------------------------------------------- /docs/coreapi/index.md: -------------------------------------------------------------------------------- 1 | # Legacy CoreAPI Schemas Docs 2 | 3 | Use of CoreAPI-based schemas were deprecated with the introduction of native OpenAPI-based schema generation in Django REST Framework v3.10. 4 | 5 | See the [Version 3.10 Release Announcement](/community/3.10-announcement.md) for more details. 6 | 7 | ---- 8 | 9 | You can continue to use CoreAPI schemas by setting the appropriate default schema class: 10 | 11 | ```python 12 | # In settings.py 13 | REST_FRAMEWORK = { 14 | 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', 15 | } 16 | ``` 17 | 18 | Under-the-hood, any subclass of `coreapi.AutoSchema` here will trigger use of the old CoreAPI schemas. 19 | **Otherwise** you will automatically be opted-in to the new OpenAPI schemas. 20 | 21 | All CoreAPI related code will be removed in Django REST Framework v3.12. Switch to OpenAPI schemas by then. 22 | 23 | ---- 24 | 25 | For reference this folder contains the old CoreAPI related documentation: 26 | 27 | * [Tutorial 7: Schemas & client libraries](https://github.com/encode/django-rest-framework/blob/master/docs/coreapi//7-schemas-and-client-libraries.md). 28 | * [Excerpts from _Documenting your API_ topic page](https://github.com/encode/django-rest-framework/blob/master/docs/coreapi//from-documenting-your-api.md). 29 | * [`rest_framework.schemas` API Reference](https://github.com/encode/django-rest-framework/blob/master/docs/coreapi//schemas.md). 30 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/pagination/numbers.html: -------------------------------------------------------------------------------- 1 | 48 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/select_multiple.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load rest_framework %} 3 | 4 | {% trans "No items to select." as no_items %} 5 | 6 |
7 | {% if field.label %} 8 | 11 | {% endif %} 12 | 13 |
14 | 27 | 28 | {% if field.errors %} 29 | {% for error in field.errors %} 30 | {{ error }} 31 | {% endfor %} 32 | {% endif %} 33 | 34 | {% if field.help_text %} 35 | {{ field.help_text|safe }} 36 | {% endif %} 37 |
38 |
39 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/auth/basic.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 | 4 | 39 | -------------------------------------------------------------------------------- /tests/test_one_to_one_with_inheritance.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.test import TestCase 3 | 4 | from rest_framework import serializers 5 | from tests.models import RESTFrameworkModel 6 | # Models 7 | from tests.test_multitable_inheritance import ChildModel 8 | 9 | 10 | # Regression test for #4290 11 | class ChildAssociatedModel(RESTFrameworkModel): 12 | child_model = models.OneToOneField(ChildModel, on_delete=models.CASCADE) 13 | child_name = models.CharField(max_length=100) 14 | 15 | 16 | # Serializers 17 | class DerivedModelSerializer(serializers.ModelSerializer): 18 | class Meta: 19 | model = ChildModel 20 | fields = ['id', 'name1', 'name2', 'childassociatedmodel'] 21 | 22 | 23 | class ChildAssociatedModelSerializer(serializers.ModelSerializer): 24 | 25 | class Meta: 26 | model = ChildAssociatedModel 27 | fields = ['id', 'child_name'] 28 | 29 | 30 | # Tests 31 | class InheritedModelSerializationTests(TestCase): 32 | 33 | def test_multitable_inherited_model_fields_as_expected(self): 34 | """ 35 | Assert that the parent pointer field is not included in the fields 36 | serialized fields 37 | """ 38 | child = ChildModel(name1='parent name', name2='child name') 39 | serializer = DerivedModelSerializer(child) 40 | self.assertEqual(set(serializer.data), 41 | {'name1', 'name2', 'id', 'childassociatedmodel'}) 42 | -------------------------------------------------------------------------------- /tests/browsable_api/test_browsable_nested_api.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from django.test import TestCase 3 | from django.test.utils import override_settings 4 | 5 | from rest_framework import serializers 6 | from rest_framework.generics import ListCreateAPIView 7 | from rest_framework.renderers import BrowsableAPIRenderer 8 | 9 | 10 | class NestedSerializer(serializers.Serializer): 11 | one = serializers.IntegerField(max_value=10) 12 | two = serializers.IntegerField(max_value=10) 13 | 14 | 15 | class NestedSerializerTestSerializer(serializers.Serializer): 16 | nested = NestedSerializer() 17 | 18 | 19 | class NestedSerializersView(ListCreateAPIView): 20 | renderer_classes = (BrowsableAPIRenderer, ) 21 | serializer_class = NestedSerializerTestSerializer 22 | queryset = [{'nested': {'one': 1, 'two': 2}}] 23 | 24 | 25 | urlpatterns = [ 26 | url(r'^api/$', NestedSerializersView.as_view(), name='api'), 27 | ] 28 | 29 | 30 | class DropdownWithAuthTests(TestCase): 31 | """Tests correct dropdown behaviour with Auth views enabled.""" 32 | 33 | @override_settings(ROOT_URLCONF='tests.browsable_api.test_browsable_nested_api') 34 | def test_login(self): 35 | response = self.client.get('/api/') 36 | assert 200 == response.status_code 37 | content = response.content.decode() 38 | assert 'form action="/api/"' in content 39 | assert 'input name="nested.one"' in content 40 | assert 'input name="nested.two"' in content 41 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/js/default.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | // JSON highlighting. 3 | prettyPrint(); 4 | 5 | // Bootstrap tooltips. 6 | $('.js-tooltip').tooltip({ 7 | delay: 1000, 8 | container: 'body' 9 | }); 10 | 11 | // Deal with rounded tab styling after tab clicks. 12 | $('a[data-toggle="tab"]:first').on('shown', function(e) { 13 | $(e.target).parents('.tabbable').addClass('first-tab-active'); 14 | }); 15 | 16 | $('a[data-toggle="tab"]:not(:first)').on('shown', function(e) { 17 | $(e.target).parents('.tabbable').removeClass('first-tab-active'); 18 | }); 19 | 20 | $('a[data-toggle="tab"]').click(function() { 21 | document.cookie = "tabstyle=" + this.name + "; path=/"; 22 | }); 23 | 24 | // Store tab preference in cookies & display appropriate tab on load. 25 | var selectedTab = null; 26 | var selectedTabName = getCookie('tabstyle'); 27 | 28 | if (selectedTabName) { 29 | selectedTabName = selectedTabName.replace(/[^a-z-]/g, ''); 30 | } 31 | 32 | if (selectedTabName) { 33 | selectedTab = $('.form-switcher a[name=' + selectedTabName + ']'); 34 | } 35 | 36 | if (selectedTab && selectedTab.length > 0) { 37 | // Display whichever tab is selected. 38 | selectedTab.tab('show'); 39 | } else { 40 | // If no tab selected, display rightmost tab. 41 | $('.form-switcher a:first').tab('show'); 42 | } 43 | 44 | $(window).on('load', function() { 45 | $('#errorModal').modal('show'); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /rest_framework/utils/humanize_datetime.py: -------------------------------------------------------------------------------- 1 | """ 2 | Helper functions that convert strftime formats into more readable representations. 3 | """ 4 | from rest_framework import ISO_8601 5 | 6 | 7 | def datetime_formats(formats): 8 | format = ', '.join(formats).replace( 9 | ISO_8601, 10 | 'YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z]' 11 | ) 12 | return humanize_strptime(format) 13 | 14 | 15 | def date_formats(formats): 16 | format = ', '.join(formats).replace(ISO_8601, 'YYYY-MM-DD') 17 | return humanize_strptime(format) 18 | 19 | 20 | def time_formats(formats): 21 | format = ', '.join(formats).replace(ISO_8601, 'hh:mm[:ss[.uuuuuu]]') 22 | return humanize_strptime(format) 23 | 24 | 25 | def humanize_strptime(format_string): 26 | # Note that we're missing some of the locale specific mappings that 27 | # don't really make sense. 28 | mapping = { 29 | "%Y": "YYYY", 30 | "%y": "YY", 31 | "%m": "MM", 32 | "%b": "[Jan-Dec]", 33 | "%B": "[January-December]", 34 | "%d": "DD", 35 | "%H": "hh", 36 | "%I": "hh", # Requires '%p' to differentiate from '%H'. 37 | "%M": "mm", 38 | "%S": "ss", 39 | "%f": "uuuuuu", 40 | "%a": "[Mon-Sun]", 41 | "%A": "[Monday-Sunday]", 42 | "%p": "[AM|PM]", 43 | "%z": "[+HHMM|-HHMM]" 44 | } 45 | for key, val in mapping.items(): 46 | format_string = format_string.replace(key, val) 47 | return format_string 48 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = 3 | {py35,py36,py37}-django22, 4 | {py36,py37,py38}-django30, 5 | {py36,py37,py38}-djangomaster, 6 | base,dist,lint,docs, 7 | 8 | [travis:env] 9 | DJANGO = 10 | 2.2: django22 11 | 3.0: django30 12 | master: djangomaster 13 | 14 | [testenv] 15 | commands = ./runtests.py --fast --coverage {posargs} 16 | envdir = {toxworkdir}/venvs/{envname} 17 | setenv = 18 | PYTHONDONTWRITEBYTECODE=1 19 | PYTHONWARNINGS=once 20 | deps = 21 | django22: Django>=2.2,<3.0 22 | django30: Django>=3.0,<3.1 23 | djangomaster: https://github.com/django/django/archive/master.tar.gz 24 | -rrequirements/requirements-testing.txt 25 | -rrequirements/requirements-optionals.txt 26 | 27 | [testenv:base] 28 | ; Ensure optional dependencies are not required 29 | deps = 30 | django 31 | -rrequirements/requirements-testing.txt 32 | 33 | [testenv:dist] 34 | commands = ./runtests.py --fast --no-pkgroot --staticfiles {posargs} 35 | deps = 36 | django 37 | -rrequirements/requirements-testing.txt 38 | -rrequirements/requirements-optionals.txt 39 | 40 | [testenv:lint] 41 | commands = ./runtests.py --lintonly 42 | deps = 43 | -rrequirements/requirements-codestyle.txt 44 | -rrequirements/requirements-testing.txt 45 | 46 | [testenv:docs] 47 | skip_install = true 48 | commands = mkdocs build 49 | deps = 50 | -rrequirements/requirements-testing.txt 51 | -rrequirements/requirements-documentation.txt 52 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/css/default.css: -------------------------------------------------------------------------------- 1 | /* The navbar is fixed at >= 980px wide, so add padding to the body to prevent 2 | content running up underneath it. */ 3 | 4 | h1 { 5 | font-weight: 300; 6 | } 7 | 8 | h2, h3 { 9 | font-weight: 300; 10 | } 11 | 12 | .resource-description, .response-info { 13 | margin-bottom: 2em; 14 | } 15 | 16 | .version:before { 17 | content: "v"; 18 | opacity: 0.6; 19 | padding-right: 0.25em; 20 | } 21 | 22 | .version { 23 | font-size: 70%; 24 | } 25 | 26 | .format-option { 27 | font-family: Menlo, Consolas, "Andale Mono", "Lucida Console", monospace; 28 | } 29 | 30 | .button-form { 31 | float: right; 32 | margin-right: 1em; 33 | } 34 | 35 | td.nested { 36 | padding: 0 !important; 37 | } 38 | 39 | td.nested > table { 40 | margin: 0; 41 | } 42 | 43 | form select, form input, form textarea { 44 | width: 90%; 45 | } 46 | 47 | form select[multiple] { 48 | height: 150px; 49 | } 50 | 51 | /* To allow tooltips to work on disabled elements */ 52 | .disabled-tooltip-shield { 53 | position: absolute; 54 | top: 0; 55 | right: 0; 56 | bottom: 0; 57 | left: 0; 58 | } 59 | 60 | .errorlist { 61 | margin-top: 0.5em; 62 | } 63 | 64 | pre { 65 | overflow: auto; 66 | word-wrap: normal; 67 | white-space: pre; 68 | font-size: 12px; 69 | } 70 | 71 | .page-header { 72 | border-bottom: none; 73 | padding-bottom: 0px; 74 | } 75 | 76 | #filtersModal form input[type=submit] { 77 | width: auto; 78 | } 79 | 80 | #filtersModal .modal-body h2 { 81 | margin-top: 0 82 | } 83 | -------------------------------------------------------------------------------- /tests/test_lazy_hyperlinks.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from django.db import models 3 | from django.test import TestCase, override_settings 4 | 5 | from rest_framework import serializers 6 | from rest_framework.renderers import JSONRenderer 7 | from rest_framework.templatetags.rest_framework import format_value 8 | 9 | str_called = False 10 | 11 | 12 | class Example(models.Model): 13 | text = models.CharField(max_length=100) 14 | 15 | def __str__(self): 16 | global str_called 17 | str_called = True 18 | return 'An example' 19 | 20 | 21 | class ExampleSerializer(serializers.HyperlinkedModelSerializer): 22 | class Meta: 23 | model = Example 24 | fields = ('url', 'id', 'text') 25 | 26 | 27 | def dummy_view(request): 28 | pass 29 | 30 | 31 | urlpatterns = [ 32 | url(r'^example/(?P[0-9]+)/$', dummy_view, name='example-detail'), 33 | ] 34 | 35 | 36 | @override_settings(ROOT_URLCONF='tests.test_lazy_hyperlinks') 37 | class TestLazyHyperlinkNames(TestCase): 38 | def setUp(self): 39 | self.example = Example.objects.create(text='foo') 40 | 41 | def test_lazy_hyperlink_names(self): 42 | global str_called 43 | context = {'request': None} 44 | serializer = ExampleSerializer(self.example, context=context) 45 | JSONRenderer().render(serializer.data) 46 | assert not str_called 47 | hyperlink_string = format_value(serializer.data['url']) 48 | assert hyperlink_string == 'An example' 49 | assert str_called 50 | -------------------------------------------------------------------------------- /rest_framework/authtoken/serializers.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import authenticate 2 | from django.utils.translation import gettext_lazy as _ 3 | 4 | from rest_framework import serializers 5 | 6 | 7 | class AuthTokenSerializer(serializers.Serializer): 8 | username = serializers.CharField( 9 | label=_("Username"), 10 | write_only=True 11 | ) 12 | password = serializers.CharField( 13 | label=_("Password"), 14 | style={'input_type': 'password'}, 15 | trim_whitespace=False, 16 | write_only=True 17 | ) 18 | token = serializers.CharField( 19 | label=_("Token"), 20 | read_only=True 21 | ) 22 | 23 | def validate(self, attrs): 24 | username = attrs.get('username') 25 | password = attrs.get('password') 26 | 27 | if username and password: 28 | user = authenticate(request=self.context.get('request'), 29 | username=username, password=password) 30 | 31 | # The authenticate call simply returns None for is_active=False 32 | # users. (Assuming the default ModelBackend authentication 33 | # backend.) 34 | if not user: 35 | msg = _('Unable to log in with provided credentials.') 36 | raise serializers.ValidationError(msg, code='authorization') 37 | else: 38 | msg = _('Must include "username" and "password".') 39 | raise serializers.ValidationError(msg, code='authorization') 40 | 41 | attrs['user'] = user 42 | return attrs 43 | -------------------------------------------------------------------------------- /rest_framework/authtoken/management/commands/drf_create_token.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.core.management.base import BaseCommand, CommandError 3 | 4 | from rest_framework.authtoken.models import Token 5 | 6 | UserModel = get_user_model() 7 | 8 | 9 | class Command(BaseCommand): 10 | help = 'Create DRF Token for a given user' 11 | 12 | def create_user_token(self, username, reset_token): 13 | user = UserModel._default_manager.get_by_natural_key(username) 14 | 15 | if reset_token: 16 | Token.objects.filter(user=user).delete() 17 | 18 | token = Token.objects.get_or_create(user=user) 19 | return token[0] 20 | 21 | def add_arguments(self, parser): 22 | parser.add_argument('username', type=str) 23 | 24 | parser.add_argument( 25 | '-r', 26 | '--reset', 27 | action='store_true', 28 | dest='reset_token', 29 | default=False, 30 | help='Reset existing User token and create a new one', 31 | ) 32 | 33 | def handle(self, *args, **options): 34 | username = options['username'] 35 | reset_token = options['reset_token'] 36 | 37 | try: 38 | token = self.create_user_token(username, reset_token) 39 | except UserModel.DoesNotExist: 40 | raise CommandError( 41 | 'Cannot create the Token: user {} does not exist'.format( 42 | username) 43 | ) 44 | self.stdout.write( 45 | 'Generated token {} for user {}'.format(token.key, username)) 46 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | Copyright © 2011-present, [Encode OSS Ltd](https://www.encode.io/). 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /tests/test_reverse.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from django.test import TestCase, override_settings 3 | from django.urls import NoReverseMatch 4 | 5 | from rest_framework.reverse import reverse 6 | from rest_framework.test import APIRequestFactory 7 | 8 | factory = APIRequestFactory() 9 | 10 | 11 | def null_view(request): 12 | pass 13 | 14 | 15 | urlpatterns = [ 16 | url(r'^view$', null_view, name='view'), 17 | ] 18 | 19 | 20 | class MockVersioningScheme: 21 | 22 | def __init__(self, raise_error=False): 23 | self.raise_error = raise_error 24 | 25 | def reverse(self, *args, **kwargs): 26 | if self.raise_error: 27 | raise NoReverseMatch() 28 | 29 | return 'http://scheme-reversed/view' 30 | 31 | 32 | @override_settings(ROOT_URLCONF='tests.test_reverse') 33 | class ReverseTests(TestCase): 34 | """ 35 | Tests for fully qualified URLs when using `reverse`. 36 | """ 37 | def test_reversed_urls_are_fully_qualified(self): 38 | request = factory.get('/view') 39 | url = reverse('view', request=request) 40 | assert url == 'http://testserver/view' 41 | 42 | def test_reverse_with_versioning_scheme(self): 43 | request = factory.get('/view') 44 | request.versioning_scheme = MockVersioningScheme() 45 | 46 | url = reverse('view', request=request) 47 | assert url == 'http://scheme-reversed/view' 48 | 49 | def test_reverse_with_versioning_scheme_fallback_to_default_on_error(self): 50 | request = factory.get('/view') 51 | request.versioning_scheme = MockVersioningScheme(raise_error=True) 52 | 53 | url = reverse('view', request=request) 54 | assert url == 'http://testserver/view' 55 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/auth/token.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 | 4 | 37 | -------------------------------------------------------------------------------- /tests/utils.py: -------------------------------------------------------------------------------- 1 | from django.core.exceptions import ObjectDoesNotExist 2 | from django.urls import NoReverseMatch 3 | 4 | 5 | class MockObject: 6 | def __init__(self, **kwargs): 7 | self._kwargs = kwargs 8 | for key, val in kwargs.items(): 9 | setattr(self, key, val) 10 | 11 | def __str__(self): 12 | kwargs_str = ', '.join([ 13 | '%s=%s' % (key, value) 14 | for key, value in sorted(self._kwargs.items()) 15 | ]) 16 | return '' % kwargs_str 17 | 18 | 19 | class MockQueryset: 20 | def __init__(self, iterable): 21 | self.items = iterable 22 | 23 | def __getitem__(self, val): 24 | return self.items[val] 25 | 26 | def get(self, **lookup): 27 | for item in self.items: 28 | if all([ 29 | getattr(item, key, None) == value 30 | for key, value in lookup.items() 31 | ]): 32 | return item 33 | raise ObjectDoesNotExist() 34 | 35 | 36 | class BadType: 37 | """ 38 | When used as a lookup with a `MockQueryset`, these objects 39 | will raise a `TypeError`, as occurs in Django when making 40 | queryset lookups with an incorrect type for the lookup value. 41 | """ 42 | def __eq__(self): 43 | raise TypeError() 44 | 45 | 46 | def mock_reverse(view_name, args=None, kwargs=None, request=None, format=None): 47 | args = args or [] 48 | kwargs = kwargs or {} 49 | value = (args + list(kwargs.values()) + ['-'])[0] 50 | prefix = 'http://example.org' if request else '' 51 | suffix = ('.' + format) if (format is not None) else '' 52 | return '%s/%s/%s%s/' % (prefix, view_name, value, suffix) 53 | 54 | 55 | def fail_reverse(view_name, args=None, kwargs=None, request=None, format=None): 56 | raise NoReverseMatch() 57 | -------------------------------------------------------------------------------- /docs/topics/writable-nested-serializers.md: -------------------------------------------------------------------------------- 1 | > To save HTTP requests, it may be convenient to send related documents along with the request. 2 | > 3 | > — [JSON API specification for Ember Data][cite]. 4 | 5 | # Writable nested serializers 6 | 7 | Although flat data structures serve to properly delineate between the individual entities in your service, there are cases where it may be more appropriate or convenient to use nested data structures. 8 | 9 | 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. 10 | 11 | ## One-to-many data structures 12 | 13 | *Example of a **read-only** nested serializer. Nothing complex to worry about here.* 14 | 15 | class ToDoItemSerializer(serializers.ModelSerializer): 16 | class Meta: 17 | model = ToDoItem 18 | fields = ['text', 'is_completed'] 19 | 20 | class ToDoListSerializer(serializers.ModelSerializer): 21 | items = ToDoItemSerializer(many=True, read_only=True) 22 | 23 | class Meta: 24 | model = ToDoList 25 | fields = ['title', 'items'] 26 | 27 | Some example output from our serializer. 28 | 29 | { 30 | 'title': 'Leaving party preparations', 31 | 'items': [ 32 | {'text': 'Compile playlist', 'is_completed': True}, 33 | {'text': 'Send invites', 'is_completed': False}, 34 | {'text': 'Clean house', 'is_completed': False} 35 | ] 36 | } 37 | 38 | Let's take a look at updating our nested one-to-many data structure. 39 | 40 | ### Validation errors 41 | 42 | ### Adding and removing items 43 | 44 | ### Making PATCH requests 45 | 46 | 47 | [cite]: http://jsonapi.org/format/#url-based-json-api 48 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/js/csrf.js: -------------------------------------------------------------------------------- 1 | function getCookie(name) { 2 | var cookieValue = null; 3 | 4 | if (document.cookie && document.cookie != '') { 5 | var cookies = document.cookie.split(';'); 6 | 7 | for (var i = 0; i < cookies.length; i++) { 8 | var cookie = jQuery.trim(cookies[i]); 9 | 10 | // Does this cookie string begin with the name we want? 11 | if (cookie.substring(0, name.length + 1) == (name + '=')) { 12 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 13 | break; 14 | } 15 | } 16 | } 17 | 18 | return cookieValue; 19 | } 20 | 21 | function csrfSafeMethod(method) { 22 | // these HTTP methods do not require CSRF protection 23 | return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 24 | } 25 | 26 | function sameOrigin(url) { 27 | // test that a given url is a same-origin URL 28 | // url could be relative or scheme relative or absolute 29 | var host = document.location.host; // host + port 30 | var protocol = document.location.protocol; 31 | var sr_origin = '//' + host; 32 | var origin = protocol + sr_origin; 33 | 34 | // Allow absolute or scheme relative URLs to same origin 35 | return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || 36 | (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || 37 | // or any other URL that isn't scheme relative or absolute i.e relative. 38 | !(/^(\/\/|http:|https:).*/.test(url)); 39 | } 40 | 41 | var csrftoken = window.drf.csrfToken; 42 | 43 | $.ajaxSetup({ 44 | beforeSend: function(xhr, settings) { 45 | if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { 46 | // Send the token to same-origin, relative URLs only. 47 | // Send the token only if the method warrants CSRF protection 48 | // Using the CSRFToken value acquired earlier 49 | xhr.setRequestHeader(window.drf.csrfHeaderName, csrftoken); 50 | } 51 | } 52 | }); 53 | -------------------------------------------------------------------------------- /rest_framework/schemas/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | rest_framework.schemas 3 | 4 | schemas: 5 | __init__.py 6 | generators.py # Top-down schema generation 7 | inspectors.py # Per-endpoint view introspection 8 | utils.py # Shared helper functions 9 | views.py # Houses `SchemaView`, `APIView` subclass. 10 | 11 | We expose a minimal "public" API directly from `schemas`. This covers the 12 | basic use-cases: 13 | 14 | from rest_framework.schemas import ( 15 | AutoSchema, 16 | ManualSchema, 17 | get_schema_view, 18 | SchemaGenerator, 19 | ) 20 | 21 | Other access should target the submodules directly 22 | """ 23 | from rest_framework.settings import api_settings 24 | 25 | from . import coreapi, openapi 26 | from .coreapi import AutoSchema, ManualSchema, SchemaGenerator # noqa 27 | from .inspectors import DefaultSchema # noqa 28 | 29 | 30 | def get_schema_view( 31 | title=None, url=None, description=None, urlconf=None, renderer_classes=None, 32 | public=False, patterns=None, generator_class=None, 33 | authentication_classes=api_settings.DEFAULT_AUTHENTICATION_CLASSES, 34 | permission_classes=api_settings.DEFAULT_PERMISSION_CLASSES, 35 | version=None): 36 | """ 37 | Return a schema view. 38 | """ 39 | if generator_class is None: 40 | if coreapi.is_enabled(): 41 | generator_class = coreapi.SchemaGenerator 42 | else: 43 | generator_class = openapi.SchemaGenerator 44 | 45 | generator = generator_class( 46 | title=title, url=url, description=description, 47 | urlconf=urlconf, patterns=patterns, version=version 48 | ) 49 | 50 | # Avoid import cycle on APIView 51 | from .views import SchemaView 52 | return SchemaView.as_view( 53 | renderer_classes=renderer_classes, 54 | schema_generator=generator, 55 | public=public, 56 | authentication_classes=authentication_classes, 57 | permission_classes=permission_classes, 58 | ) 59 | -------------------------------------------------------------------------------- /rest_framework/schemas/views.py: -------------------------------------------------------------------------------- 1 | """ 2 | views.py # Houses `SchemaView`, `APIView` subclass. 3 | 4 | See schemas.__init__.py for package overview. 5 | """ 6 | from rest_framework import exceptions, renderers 7 | from rest_framework.response import Response 8 | from rest_framework.schemas import coreapi 9 | from rest_framework.settings import api_settings 10 | from rest_framework.views import APIView 11 | 12 | 13 | class SchemaView(APIView): 14 | _ignore_model_permissions = True 15 | schema = None # exclude from schema 16 | renderer_classes = None 17 | schema_generator = None 18 | public = False 19 | 20 | def __init__(self, *args, **kwargs): 21 | super().__init__(*args, **kwargs) 22 | if self.renderer_classes is None: 23 | if coreapi.is_enabled(): 24 | self.renderer_classes = [ 25 | renderers.CoreAPIOpenAPIRenderer, 26 | renderers.CoreJSONRenderer 27 | ] 28 | else: 29 | self.renderer_classes = [ 30 | renderers.OpenAPIRenderer, 31 | renderers.JSONOpenAPIRenderer, 32 | ] 33 | if renderers.BrowsableAPIRenderer in api_settings.DEFAULT_RENDERER_CLASSES: 34 | self.renderer_classes += [renderers.BrowsableAPIRenderer] 35 | 36 | def get(self, request, *args, **kwargs): 37 | schema = self.schema_generator.get_schema(request, self.public) 38 | if schema is None: 39 | raise exceptions.PermissionDenied() 40 | return Response(schema) 41 | 42 | def handle_exception(self, exc): 43 | # Schema renderers do not render exceptions, so re-perform content 44 | # negotiation with default renderers. 45 | self.renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES 46 | neg = self.perform_content_negotiation(self.request, force=True) 47 | self.request.accepted_renderer, self.request.accepted_media_type = neg 48 | return super().handle_exception(exc) 49 | -------------------------------------------------------------------------------- /docs/api-guide/caching.md: -------------------------------------------------------------------------------- 1 | # Caching 2 | 3 | > A certain woman had a very sharp consciousness but almost no 4 | > memory ... She remembered enough to work, and she worked hard. 5 | > - Lydia Davis 6 | 7 | Caching in REST Framework works well with the cache utilities 8 | provided in Django. 9 | 10 | --- 11 | 12 | ## Using cache with apiview and viewsets 13 | 14 | Django provides a [`method_decorator`][decorator] to use 15 | decorators with class based views. This can be used with 16 | other cache decorators such as [`cache_page`][page] and 17 | [`vary_on_cookie`][cookie]. 18 | 19 | ```python 20 | from django.utils.decorators import method_decorator 21 | from django.views.decorators.cache import cache_page 22 | from django.views.decorators.vary import vary_on_cookie 23 | 24 | from rest_framework.response import Response 25 | from rest_framework.views import APIView 26 | from rest_framework import viewsets 27 | 28 | 29 | class UserViewSet(viewsets.ViewSet): 30 | 31 | # Cache requested url for each user for 2 hours 32 | @method_decorator(cache_page(60*60*2)) 33 | @method_decorator(vary_on_cookie) 34 | def list(self, request, format=None): 35 | content = { 36 | 'user_feed': request.user.get_user_feed() 37 | } 38 | return Response(content) 39 | 40 | 41 | class PostView(APIView): 42 | 43 | # Cache page for the requested url 44 | @method_decorator(cache_page(60*60*2)) 45 | def get(self, request, format=None): 46 | content = { 47 | 'title': 'Post title', 48 | 'body': 'Post content' 49 | } 50 | return Response(content) 51 | ``` 52 | 53 | **NOTE:** The [`cache_page`][page] decorator only caches the 54 | `GET` and `HEAD` responses with status 200. 55 | 56 | [page]: https://docs.djangoproject.com/en/dev/topics/cache/#the-per-view-cache 57 | [cookie]: https://docs.djangoproject.com/en/dev/topics/http/decorators/#django.views.decorators.vary.vary_on_cookie 58 | [decorator]: https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/#decorating-the-class 59 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/horizontal/radio.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load rest_framework %} 3 | 4 | {% trans "None" as none_choice %} 5 | 6 |
7 | {% if field.label %} 8 | 11 | {% endif %} 12 | 13 |
14 | {% if style.inline %} 15 | {% if field.allow_null or field.allow_blank %} 16 | 20 | {% endif %} 21 | 22 | {% for key, text in field.choices|items %} 23 | 27 | {% endfor %} 28 | {% else %} 29 | {% if field.allow_null or field.allow_blank %} 30 |
31 | 35 |
36 | {% endif %} 37 | {% for key, text in field.choices|items %} 38 |
39 | 43 |
44 | {% endfor %} 45 | {% endif %} 46 | 47 | {% if field.errors %} 48 | {% for error in field.errors %} 49 | {{ error }} 50 | {% endfor %} 51 | {% endif %} 52 | 53 | {% if field.help_text %} 54 | {{ field.help_text|safe }} 55 | {% endif %} 56 |
57 |
58 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/interact.html: -------------------------------------------------------------------------------- 1 | {% load rest_framework %} 2 | 3 | 4 | 52 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/vertical/radio.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load rest_framework %} 3 | {% trans "None" as none_choice %} 4 | 5 |
6 | {% if field.label %} 7 | 10 | {% endif %} 11 | 12 | {% if style.inline %} 13 |
14 | {% if field.allow_null or field.allow_blank %} 15 | 19 | {% endif %} 20 | 21 | {% for key, text in field.choices|items %} 22 | 26 | {% endfor %} 27 |
28 | {% else %} 29 | {% if field.allow_null or field.allow_blank %} 30 |
31 | 35 |
36 | {% endif %} 37 | 38 | {% for key, text in field.choices|items %} 39 |
40 | 44 |
45 | {% endfor %} 46 | {% endif %} 47 | 48 | {% if field.errors %} 49 | {% for error in field.errors %} 50 | {{ error }} 51 | {% endfor %} 52 | {% endif %} 53 | 54 | {% if field.help_text %} 55 | {{ field.help_text|safe }} 56 | {% endif %} 57 |
58 | -------------------------------------------------------------------------------- /tests/test_settings.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase, override_settings 2 | 3 | from rest_framework.settings import APISettings, api_settings 4 | 5 | 6 | class TestSettings(TestCase): 7 | def test_import_error_message_maintained(self): 8 | """ 9 | Make sure import errors are captured and raised sensibly. 10 | """ 11 | settings = APISettings({ 12 | 'DEFAULT_RENDERER_CLASSES': [ 13 | 'tests.invalid_module.InvalidClassName' 14 | ] 15 | }) 16 | with self.assertRaises(ImportError): 17 | settings.DEFAULT_RENDERER_CLASSES 18 | 19 | def test_warning_raised_on_removed_setting(self): 20 | """ 21 | Make sure user is alerted with an error when a removed setting 22 | is set. 23 | """ 24 | with self.assertRaises(RuntimeError): 25 | APISettings({ 26 | 'MAX_PAGINATE_BY': 100 27 | }) 28 | 29 | def test_compatibility_with_override_settings(self): 30 | """ 31 | Ref #5658 & #2466: Documented usage of api_settings 32 | is bound at import time: 33 | 34 | from rest_framework.settings import api_settings 35 | 36 | setting_changed signal hook must ensure bound instance 37 | is refreshed. 38 | """ 39 | assert api_settings.PAGE_SIZE is None, "Checking a known default should be None" 40 | 41 | with override_settings(REST_FRAMEWORK={'PAGE_SIZE': 10}): 42 | assert api_settings.PAGE_SIZE == 10, "Setting should have been updated" 43 | 44 | assert api_settings.PAGE_SIZE is None, "Setting should have been restored" 45 | 46 | 47 | class TestSettingTypes(TestCase): 48 | def test_settings_consistently_coerced_to_list(self): 49 | settings = APISettings({ 50 | 'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.BaseThrottle',) 51 | }) 52 | self.assertTrue(isinstance(settings.DEFAULT_THROTTLE_CLASSES, list)) 53 | 54 | settings = APISettings({ 55 | 'DEFAULT_THROTTLE_CLASSES': () 56 | }) 57 | self.assertTrue(isinstance(settings.DEFAULT_THROTTLE_CLASSES, list)) 58 | -------------------------------------------------------------------------------- /rest_framework/templates/rest_framework/docs/error.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Error Rendering Schema 10 | 11 | 12 | 13 | 14 | 15 |

Error

16 | 17 |
18 | {{ data }}
19 | 
20 | 21 | 22 | {% if debug is True %} 23 |
24 |

Additional Information

25 |

Note: You are seeing this message because DEBUG==True.

26 | 27 |

Seeing this page is usually a configuration error: are your 28 | DEFAULT_AUTHENTICATION_CLASSES or DEFAULT_PERMISSION_CLASSES 29 | being applied unexpectedly?

30 | 31 |

Your response status code is: {{ response.status_code }}

32 | 33 |

401 Unauthorised.

34 | 38 | 39 | 40 |

403 Forbidden.

41 | 45 | 46 | 47 |

Most commonly the intended solution is to disable authentication and permissions 48 | when including the docs urls:

49 | 50 |
51 |    url(r'^docs/', include_docs_urls(title='Your API',
52 |                                     authentication_classes=[],
53 |                                     permission_classes=[])),
54 | 
55 | 56 | 57 |

Overriding this template

58 | 59 |

If you wish access to your docs to be authenticated you may override this template 60 | at rest_framework/docs/error.html.

61 | 62 |

The available context is: data the error dict above, request, 63 | response and the debug flag.

64 | 65 | {% endif %} 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /tests/test_prefetch_related.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.models import Group, User 2 | from django.test import TestCase 3 | 4 | from rest_framework import generics, serializers 5 | from rest_framework.test import APIRequestFactory 6 | 7 | factory = APIRequestFactory() 8 | 9 | 10 | class UserSerializer(serializers.ModelSerializer): 11 | class Meta: 12 | model = User 13 | fields = ('id', 'username', 'email', 'groups') 14 | 15 | 16 | class UserUpdate(generics.UpdateAPIView): 17 | queryset = User.objects.exclude(username='exclude').prefetch_related('groups') 18 | serializer_class = UserSerializer 19 | 20 | 21 | class TestPrefetchRelatedUpdates(TestCase): 22 | def setUp(self): 23 | self.user = User.objects.create(username='tom', email='tom@example.com') 24 | self.groups = [Group.objects.create(name='a'), Group.objects.create(name='b')] 25 | self.user.groups.set(self.groups) 26 | 27 | def test_prefetch_related_updates(self): 28 | view = UserUpdate.as_view() 29 | pk = self.user.pk 30 | groups_pk = self.groups[0].pk 31 | request = factory.put('/', {'username': 'new', 'groups': [groups_pk]}, format='json') 32 | response = view(request, pk=pk) 33 | assert User.objects.get(pk=pk).groups.count() == 1 34 | expected = { 35 | 'id': pk, 36 | 'username': 'new', 37 | 'groups': [1], 38 | 'email': 'tom@example.com' 39 | } 40 | assert response.data == expected 41 | 42 | def test_prefetch_related_excluding_instance_from_original_queryset(self): 43 | """ 44 | Regression test for https://github.com/encode/django-rest-framework/issues/4661 45 | """ 46 | view = UserUpdate.as_view() 47 | pk = self.user.pk 48 | groups_pk = self.groups[0].pk 49 | request = factory.put('/', {'username': 'exclude', 'groups': [groups_pk]}, format='json') 50 | response = view(request, pk=pk) 51 | assert User.objects.get(pk=pk).groups.count() == 1 52 | expected = { 53 | 'id': pk, 54 | 'username': 'exclude', 55 | 'groups': [1], 56 | 'email': 'tom@example.com' 57 | } 58 | assert response.data == expected 59 | -------------------------------------------------------------------------------- /rest_framework/utils/breadcrumbs.py: -------------------------------------------------------------------------------- 1 | from django.urls import get_script_prefix, resolve 2 | 3 | 4 | def get_breadcrumbs(url, request=None): 5 | """ 6 | Given a url returns a list of breadcrumbs, which are each a 7 | tuple of (name, url). 8 | """ 9 | from rest_framework.reverse import preserve_builtin_query_params 10 | from rest_framework.views import APIView 11 | 12 | def breadcrumbs_recursive(url, breadcrumbs_list, prefix, seen): 13 | """ 14 | Add tuples of (name, url) to the breadcrumbs list, 15 | progressively chomping off parts of the url. 16 | """ 17 | try: 18 | (view, unused_args, unused_kwargs) = resolve(url) 19 | except Exception: 20 | pass 21 | else: 22 | # Check if this is a REST framework view, 23 | # and if so add it to the breadcrumbs 24 | cls = getattr(view, 'cls', None) 25 | initkwargs = getattr(view, 'initkwargs', {}) 26 | if cls is not None and issubclass(cls, APIView): 27 | # Don't list the same view twice in a row. 28 | # Probably an optional trailing slash. 29 | if not seen or seen[-1] != view: 30 | c = cls(**initkwargs) 31 | name = c.get_view_name() 32 | insert_url = preserve_builtin_query_params(prefix + url, request) 33 | breadcrumbs_list.insert(0, (name, insert_url)) 34 | seen.append(view) 35 | 36 | if url == '': 37 | # All done 38 | return breadcrumbs_list 39 | 40 | elif url.endswith('/'): 41 | # Drop trailing slash off the end and continue to try to 42 | # resolve more breadcrumbs 43 | url = url.rstrip('/') 44 | return breadcrumbs_recursive(url, breadcrumbs_list, prefix, seen) 45 | 46 | # Drop trailing non-slash off the end and continue to try to 47 | # resolve more breadcrumbs 48 | url = url[:url.rfind('/') + 1] 49 | return breadcrumbs_recursive(url, breadcrumbs_list, prefix, seen) 50 | 51 | prefix = get_script_prefix().rstrip('/') 52 | url = url[len(prefix):] 53 | return breadcrumbs_recursive(url, [], prefix, []) 54 | -------------------------------------------------------------------------------- /docs/community/jobs.md: -------------------------------------------------------------------------------- 1 | # Jobs 2 | 3 | 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]. 4 | 5 | 6 | ## Places to look for Django REST Framework Jobs 7 | 8 | * [https://www.djangoproject.com/community/jobs/][djangoproject-website] 9 | * [https://www.python.org/jobs/][python-org-jobs] 10 | * [https://djangogigs.com][django-gigs-com] 11 | * [https://djangojobs.net/jobs/][django-jobs-net] 12 | * [https://findwork.dev/django-rest-framework-jobs][findwork-dev] 13 | * [https://www.indeed.com/q-Django-jobs.html][indeed-com] 14 | * [https://stackoverflow.com/jobs/developer-jobs-using-django][stackoverflow-com] 15 | * [https://www.upwork.com/o/jobs/browse/skill/django-framework/][upwork-com] 16 | * [https://www.technojobs.co.uk/django-jobs][technobjobs-co-uk] 17 | * [https://remoteok.io/remote-django-jobs][remoteok-io] 18 | * [https://www.remotepython.com/jobs/][remotepython-com] 19 | 20 | 21 | 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]. 22 | 23 | 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. 24 | 25 | 26 | [djangoproject-website]: https://www.djangoproject.com/community/jobs/ 27 | [python-org-jobs]: https://www.python.org/jobs/ 28 | [django-gigs-com]: https://djangogigs.com 29 | [django-jobs-net]: https://djangojobs.net/jobs/ 30 | [findwork-dev]: https://findwork.dev/django-rest-framework-jobs 31 | [indeed-com]: https://www.indeed.com/q-Django-jobs.html 32 | [stackoverflow-com]: https://stackoverflow.com/jobs/developer-jobs-using-django 33 | [upwork-com]: https://www.upwork.com/o/jobs/browse/skill/django-framework/ 34 | [technobjobs-co-uk]: https://www.technojobs.co.uk/django-jobs 35 | [remoteok-io]: https://remoteok.io/remote-django-jobs 36 | [remotepython-com]: https://www.remotepython.com/jobs/ 37 | [drf-funding]: https://fund.django-rest-framework.org/topics/funding/ 38 | [submit-pr]: https://github.com/encode/django-rest-framework 39 | [anna-email]: mailto:anna@django-rest-framework.org 40 | -------------------------------------------------------------------------------- /tests/test_multitable_inheritance.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.test import TestCase 3 | 4 | from rest_framework import serializers 5 | from tests.models import RESTFrameworkModel 6 | 7 | 8 | # Models 9 | class ParentModel(RESTFrameworkModel): 10 | name1 = models.CharField(max_length=100) 11 | 12 | 13 | class ChildModel(ParentModel): 14 | name2 = models.CharField(max_length=100) 15 | 16 | 17 | class AssociatedModel(RESTFrameworkModel): 18 | ref = models.OneToOneField(ParentModel, primary_key=True, on_delete=models.CASCADE) 19 | name = models.CharField(max_length=100) 20 | 21 | 22 | # Serializers 23 | class DerivedModelSerializer(serializers.ModelSerializer): 24 | class Meta: 25 | model = ChildModel 26 | fields = '__all__' 27 | 28 | 29 | class AssociatedModelSerializer(serializers.ModelSerializer): 30 | class Meta: 31 | model = AssociatedModel 32 | fields = '__all__' 33 | 34 | 35 | # Tests 36 | class InheritedModelSerializationTests(TestCase): 37 | 38 | def test_multitable_inherited_model_fields_as_expected(self): 39 | """ 40 | Assert that the parent pointer field is not included in the fields 41 | serialized fields 42 | """ 43 | child = ChildModel(name1='parent name', name2='child name') 44 | serializer = DerivedModelSerializer(child) 45 | assert set(serializer.data) == {'name1', 'name2', 'id'} 46 | 47 | def test_onetoone_primary_key_model_fields_as_expected(self): 48 | """ 49 | Assert that a model with a onetoone field that is the primary key is 50 | not treated like a derived model 51 | """ 52 | parent = ParentModel.objects.create(name1='parent name') 53 | associate = AssociatedModel.objects.create(name='hello', ref=parent) 54 | serializer = AssociatedModelSerializer(associate) 55 | assert set(serializer.data) == {'name', 'ref'} 56 | 57 | def test_data_is_valid_without_parent_ptr(self): 58 | """ 59 | Assert that the pointer to the parent table is not a required field 60 | for input data 61 | """ 62 | data = { 63 | 'name1': 'parent name', 64 | 'name2': 'child name', 65 | } 66 | serializer = DerivedModelSerializer(data=data) 67 | assert serializer.is_valid() is True 68 | -------------------------------------------------------------------------------- /tests/generic_relations/test_generic_relations.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | from rest_framework import serializers 4 | 5 | from .models import Bookmark, Note, Tag 6 | 7 | 8 | class TestGenericRelations(TestCase): 9 | def setUp(self): 10 | self.bookmark = Bookmark.objects.create(url='https://www.djangoproject.com/') 11 | Tag.objects.create(tagged_item=self.bookmark, tag='django') 12 | Tag.objects.create(tagged_item=self.bookmark, tag='python') 13 | self.note = Note.objects.create(text='Remember the milk') 14 | Tag.objects.create(tagged_item=self.note, tag='reminder') 15 | 16 | def test_generic_relation(self): 17 | """ 18 | Test a relationship that spans a GenericRelation field. 19 | IE. A reverse generic relationship. 20 | """ 21 | 22 | class BookmarkSerializer(serializers.ModelSerializer): 23 | tags = serializers.StringRelatedField(many=True) 24 | 25 | class Meta: 26 | model = Bookmark 27 | fields = ('tags', 'url') 28 | 29 | serializer = BookmarkSerializer(self.bookmark) 30 | expected = { 31 | 'tags': ['django', 'python'], 32 | 'url': 'https://www.djangoproject.com/' 33 | } 34 | assert serializer.data == expected 35 | 36 | def test_generic_fk(self): 37 | """ 38 | Test a relationship that spans a GenericForeignKey field. 39 | IE. A forward generic relationship. 40 | """ 41 | 42 | class TagSerializer(serializers.ModelSerializer): 43 | tagged_item = serializers.StringRelatedField() 44 | 45 | class Meta: 46 | model = Tag 47 | fields = ('tag', 'tagged_item') 48 | 49 | serializer = TagSerializer(Tag.objects.all(), many=True) 50 | expected = [ 51 | { 52 | 'tag': 'django', 53 | 'tagged_item': 'Bookmark: https://www.djangoproject.com/' 54 | }, 55 | { 56 | 'tag': 'python', 57 | 'tagged_item': 'Bookmark: https://www.djangoproject.com/' 58 | }, 59 | { 60 | 'tag': 'reminder', 61 | 'tagged_item': 'Note: Remember the milk' 62 | } 63 | ] 64 | assert serializer.data == expected 65 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/docs/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* 2 | This is the GitHub theme for highlight.js 3 | 4 | github.com style (c) Vasily Polovnyov 5 | 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | color: #333; 13 | -webkit-text-size-adjust: none; 14 | } 15 | 16 | .hljs-comment, 17 | .diff .hljs-header, 18 | .hljs-javadoc { 19 | color: #998; 20 | font-style: italic; 21 | } 22 | 23 | .hljs-keyword, 24 | .css .rule .hljs-keyword, 25 | .hljs-winutils, 26 | .nginx .hljs-title, 27 | .hljs-subst, 28 | .hljs-request, 29 | .hljs-status { 30 | color: #333; 31 | font-weight: bold; 32 | } 33 | 34 | .hljs-number, 35 | .hljs-hexcolor, 36 | .ruby .hljs-constant { 37 | color: #008080; 38 | } 39 | 40 | .hljs-string, 41 | .hljs-tag .hljs-value, 42 | .hljs-phpdoc, 43 | .hljs-dartdoc, 44 | .tex .hljs-formula { 45 | color: #d14; 46 | } 47 | 48 | .hljs-title, 49 | .hljs-id, 50 | .scss .hljs-preprocessor { 51 | color: #900; 52 | font-weight: bold; 53 | } 54 | 55 | .hljs-list .hljs-keyword, 56 | .hljs-subst { 57 | font-weight: normal; 58 | } 59 | 60 | .hljs-class .hljs-title, 61 | .hljs-type, 62 | .vhdl .hljs-literal, 63 | .tex .hljs-command { 64 | color: #458; 65 | font-weight: bold; 66 | } 67 | 68 | .hljs-tag, 69 | .hljs-tag .hljs-title, 70 | .hljs-rule .hljs-property, 71 | .django .hljs-tag .hljs-keyword { 72 | color: #000080; 73 | font-weight: normal; 74 | } 75 | 76 | .hljs-attribute, 77 | .hljs-variable, 78 | .lisp .hljs-body, 79 | .hljs-name { 80 | color: #008080; 81 | } 82 | 83 | .hljs-regexp { 84 | color: #009926; 85 | } 86 | 87 | .hljs-symbol, 88 | .ruby .hljs-symbol .hljs-string, 89 | .lisp .hljs-keyword, 90 | .clojure .hljs-keyword, 91 | .scheme .hljs-keyword, 92 | .tex .hljs-special, 93 | .hljs-prompt { 94 | color: #990073; 95 | } 96 | 97 | .hljs-built_in { 98 | color: #0086b3; 99 | } 100 | 101 | .hljs-preprocessor, 102 | .hljs-pragma, 103 | .hljs-pi, 104 | .hljs-doctype, 105 | .hljs-shebang, 106 | .hljs-cdata { 107 | color: #999; 108 | font-weight: bold; 109 | } 110 | 111 | .hljs-deletion { 112 | background: #fdd; 113 | } 114 | 115 | .hljs-addition { 116 | background: #dfd; 117 | } 118 | 119 | .diff .hljs-change { 120 | background: #0086b3; 121 | } 122 | 123 | .hljs-chunk { 124 | color: #aaa; 125 | } 126 | -------------------------------------------------------------------------------- /rest_framework/reverse.py: -------------------------------------------------------------------------------- 1 | """ 2 | Provide urlresolver functions that return fully qualified URLs or view names 3 | """ 4 | from django.urls import NoReverseMatch 5 | from django.urls import reverse as django_reverse 6 | from django.utils.functional import lazy 7 | 8 | from rest_framework.settings import api_settings 9 | from rest_framework.utils.urls import replace_query_param 10 | 11 | 12 | def preserve_builtin_query_params(url, request=None): 13 | """ 14 | Given an incoming request, and an outgoing URL representation, 15 | append the value of any built-in query parameters. 16 | """ 17 | if request is None: 18 | return url 19 | 20 | overrides = [ 21 | api_settings.URL_FORMAT_OVERRIDE, 22 | ] 23 | 24 | for param in overrides: 25 | if param and (param in request.GET): 26 | value = request.GET[param] 27 | url = replace_query_param(url, param, value) 28 | 29 | return url 30 | 31 | 32 | def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra): 33 | """ 34 | If versioning is being used then we pass any `reverse` calls through 35 | to the versioning scheme instance, so that the resulting URL 36 | can be modified if needed. 37 | """ 38 | scheme = getattr(request, 'versioning_scheme', None) 39 | if scheme is not None: 40 | try: 41 | url = scheme.reverse(viewname, args, kwargs, request, format, **extra) 42 | except NoReverseMatch: 43 | # In case the versioning scheme reversal fails, fallback to the 44 | # default implementation 45 | url = _reverse(viewname, args, kwargs, request, format, **extra) 46 | else: 47 | url = _reverse(viewname, args, kwargs, request, format, **extra) 48 | 49 | return preserve_builtin_query_params(url, request) 50 | 51 | 52 | def _reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra): 53 | """ 54 | Same as `django.urls.reverse`, but optionally takes a request 55 | and returns a fully qualified URL, using the request to get the base URL. 56 | """ 57 | if format is not None: 58 | kwargs = kwargs or {} 59 | kwargs['format'] = format 60 | url = django_reverse(viewname, args=args, kwargs=kwargs, **extra) 61 | if request: 62 | return request.build_absolute_uri(url) 63 | return url 64 | 65 | 66 | reverse_lazy = lazy(reverse, str) 67 | -------------------------------------------------------------------------------- /rest_framework/authtoken/views.py: -------------------------------------------------------------------------------- 1 | from rest_framework import parsers, renderers 2 | from rest_framework.authtoken.models import Token 3 | from rest_framework.authtoken.serializers import AuthTokenSerializer 4 | from rest_framework.compat import coreapi, coreschema 5 | from rest_framework.response import Response 6 | from rest_framework.schemas import ManualSchema 7 | from rest_framework.schemas import coreapi as coreapi_schema 8 | from rest_framework.views import APIView 9 | 10 | 11 | class ObtainAuthToken(APIView): 12 | throttle_classes = () 13 | permission_classes = () 14 | parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) 15 | renderer_classes = (renderers.JSONRenderer,) 16 | serializer_class = AuthTokenSerializer 17 | 18 | if coreapi_schema.is_enabled(): 19 | schema = ManualSchema( 20 | fields=[ 21 | coreapi.Field( 22 | name="username", 23 | required=True, 24 | location='form', 25 | schema=coreschema.String( 26 | title="Username", 27 | description="Valid username for authentication", 28 | ), 29 | ), 30 | coreapi.Field( 31 | name="password", 32 | required=True, 33 | location='form', 34 | schema=coreschema.String( 35 | title="Password", 36 | description="Valid password for authentication", 37 | ), 38 | ), 39 | ], 40 | encoding="application/json", 41 | ) 42 | 43 | def get_serializer_context(self): 44 | return { 45 | 'request': self.request, 46 | 'format': self.format_kwarg, 47 | 'view': self 48 | } 49 | 50 | def get_serializer(self, *args, **kwargs): 51 | kwargs['context'] = self.get_serializer_context() 52 | return self.serializer_class(*args, **kwargs) 53 | 54 | def post(self, request, *args, **kwargs): 55 | serializer = self.get_serializer(data=request.data) 56 | serializer.is_valid(raise_exception=True) 57 | user = serializer.validated_data['user'] 58 | token, created = Token.objects.get_or_create(user=user) 59 | return Response({'token': token.key}) 60 | 61 | 62 | obtain_auth_token = ObtainAuthToken.as_view() 63 | -------------------------------------------------------------------------------- /docs_theme/nav.html: -------------------------------------------------------------------------------- 1 | 47 | -------------------------------------------------------------------------------- /docs/api-guide/reverse.md: -------------------------------------------------------------------------------- 1 | --- 2 | source: 3 | - reverse.py 4 | --- 5 | 6 | # Returning URLs 7 | 8 | > The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components. 9 | > 10 | > — Roy Fielding, [Architectural Styles and the Design of Network-based Software Architectures][cite] 11 | 12 | As a rule, it's probably better practice to return absolute URIs from your Web APIs, such as `http://example.com/foobar`, rather than returning relative URIs, such as `/foobar`. 13 | 14 | The advantages of doing so are: 15 | 16 | * It's more explicit. 17 | * It leaves less work for your API clients. 18 | * There's no ambiguity about the meaning of the string when it's found in representations such as JSON that do not have a native URI type. 19 | * It makes it easy to do things like markup HTML representations with hyperlinks. 20 | 21 | REST framework provides two utility functions to make it more simple to return absolute URIs from your Web API. 22 | 23 | There's no requirement for you to use them, but if you do then the self-describing API will be able to automatically hyperlink its output for you, which makes browsing the API much easier. 24 | 25 | ## reverse 26 | 27 | **Signature:** `reverse(viewname, *args, **kwargs)` 28 | 29 | Has the same behavior as [`django.urls.reverse`][reverse], except that it returns a fully qualified URL, using the request to determine the host and port. 30 | 31 | You should **include the request as a keyword argument** to the function, for example: 32 | 33 | from rest_framework.reverse import reverse 34 | from rest_framework.views import APIView 35 | from django.utils.timezone import now 36 | 37 | class APIRootView(APIView): 38 | def get(self, request): 39 | year = now().year 40 | data = { 41 | ... 42 | 'year-summary-url': reverse('year-summary', args=[year], request=request) 43 | } 44 | return Response(data) 45 | 46 | ## reverse_lazy 47 | 48 | **Signature:** `reverse_lazy(viewname, *args, **kwargs)` 49 | 50 | Has the same behavior as [`django.urls.reverse_lazy`][reverse-lazy], except that it returns a fully qualified URL, using the request to determine the host and port. 51 | 52 | As with the `reverse` function, you should **include the request as a keyword argument** to the function, for example: 53 | 54 | api_root = reverse_lazy('api-root', request=request) 55 | 56 | [cite]: https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5 57 | [reverse]: https://docs.djangoproject.com/en/stable/topics/http/urls/#reverse 58 | [reverse-lazy]: https://docs.djangoproject.com/en/stable/topics/http/urls/#reverse-lazy 59 | -------------------------------------------------------------------------------- /rest_framework/static/rest_framework/docs/js/jquery.json-view.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.json-view - jQuery collapsible JSON plugin 3 | * @version v1.0.0 4 | * @link http://github.com/bazh/jquery.json-view 5 | * @license MIT 6 | */ 7 | !function(e){"use strict";var n=function(n){var a=e("",{"class":"collapser",on:{click:function(){var n=e(this);n.toggleClass("collapsed");var a=n.parent().children(".block"),p=a.children("ul");n.hasClass("collapsed")?(p.hide(),a.children(".dots, .comments").show()):(p.show(),a.children(".dots, .comments").hide())}}});return n&&a.addClass("collapsed"),a},a=function(a,p){var t=e.extend({},{nl2br:!0},p),r=function(e){return e.toString()?e.toString().replace(/&/g,"&").replace(/"/g,""").replace(//g,">"):""},s=function(n,a){return e("",{"class":a,html:r(n)})},l=function(a,p){switch(e.type(a)){case"object":p||(p=0);var c=e("",{"class":"block"}),d=Object.keys(a).length;if(!d)return c.append(s("{","b")).append(" ").append(s("}","b"));c.append(s("{","b"));var i=e("