mirror of
https://github.com/encode/django-rest-framework.git
synced 2026-01-15 04:48:47 +03:00
Update documentation
This commit is contained in:
parent
5769306c10
commit
330c13296d
283
404.html
283
404.html
|
|
@ -1,112 +1,116 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Django REST framework - 404 - Page not found</title>
|
||||
<link href="http://django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://django-rest-framework.org/404"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, 404 - Page not found">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Django REST framework - 404 - Page not found</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/404" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, 404 - Page not found">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="404-page">
|
||||
<body onload="prettyPrint()" class="404-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small disabled" href="#">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small disabled" href="#"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small disabled" href="#">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small disabled" href="#"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://django-rest-framework.org">Django REST framework</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://django-rest-framework.org">Home</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -121,81 +125,92 @@
|
|||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div id="main-content" class="span12">
|
||||
<h1 id="404-page-not-found" style="text-align: center">404</h1>
|
||||
<p style="text-align: center"><strong>Page not found</strong></p>
|
||||
<p style="text-align: center">Try the <a href="http://django-rest-framework.org/">homepage</a>, or <a href="#searchModal" data-toggle="modal">search the documentation</a>.</p>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
<p style="text-align: center"><strong>Page not found</strong>
|
||||
</p>
|
||||
<p style="text-align: center">Try the <a href="http://www.django-rest-framework.org/">homepage</a>, or <a href="#searchModal" data-toggle="modal">search the documentation</a>.</p>
|
||||
</div>
|
||||
<!--/span-->
|
||||
</div>
|
||||
<!--/row-->
|
||||
</div>
|
||||
<!--/.fluid-container-->
|
||||
</div>
|
||||
<!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
<!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://www.django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
</html>
|
||||
|
|
@ -1,65 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Authentication - Django REST framework</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/authentication"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Authentication, API Reference, Custom authentication, Third party packages">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Authentication - Django REST framework</title>
|
||||
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/authentication/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Authentication">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<!-- Le styles -->
|
||||
<link href="../../css/prettify.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="../../css/default.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="authentication-page">
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/permissions">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/relations"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../permissions">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../validators">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
|
|
@ -67,80 +76,218 @@ a.fusion-poweredby {
|
|||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li ><a href="/">Home</a></li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/quickstart">Quickstart</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/1-serialization">1 - Serialization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/2-requests-and-responses">2 - Requests and responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/3-class-based-views">3 - Class based views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/6-viewsets-and-routers">6- Viewsets and routers</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../requests">Requests</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../responses">Responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../views">Views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../generic-views">Generic views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../viewsets">Viewsets</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../routers">Routers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../parsers">Parsers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../renderers">Renderers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../serializers">Serializers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../fields">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../relations">Serializer relations</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../validators">Validators</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href=".">Authentication</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../permissions">Permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../throttling">Throttling</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../filtering">Filtering</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../pagination">Pagination</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../content-negotiation">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../format-suffixes">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../reverse">Returning URLs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../exceptions">Exceptions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../status-codes">Status codes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../testing">Testing</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../settings">Settings</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/third-party-resources">Third Party Resources</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/contributing">Contributing to REST framework</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.4-announcement">2.4 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/kickstarter-announcement">Kickstarter Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/documenting-your-api">Documenting your API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/ajax-csrf-cors">AJAX, CSRF & CORS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browser-enhancements">Browser enhancements</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browsable-api">The Browsable API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/third-party-resources">Third Party Resources</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/contributing">Contributing to REST framework</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-framework-2-announcement">2.0 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.2-announcement">2.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.3-announcement">2.3 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.4-announcement">2.4 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/release-notes">Release Notes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/credits">Credits</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<!-- TODO
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Version: 2.0.0 <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Trunk</a></li>
|
||||
<li><a href="#">2.0.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -148,32 +295,34 @@ a.fusion-poweredby {
|
|||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
|
|
@ -186,51 +335,140 @@ a.fusion-poweredby {
|
|||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
<li class="main"><a href="#authentication">Authentication</a></li>
|
||||
<li><a href="#how-authentication-is-determined">How authentication is determined</a></li>
|
||||
<li><a href="#setting-the-authentication-scheme">Setting the authentication scheme</a></li>
|
||||
<li><a href="#unauthorized-and-forbidden-responses">Unauthorized and Forbidden responses</a></li>
|
||||
<li><a href="#apache-mod_wsgi-specific-configuration">Apache mod_wsgi specific configuration</a></li>
|
||||
<li class="main"><a href="#api-reference">API Reference</a></li>
|
||||
<li><a href="#basicauthentication">BasicAuthentication</a></li>
|
||||
<li><a href="#tokenauthentication">TokenAuthentication</a></li>
|
||||
<li><a href="#sessionauthentication">SessionAuthentication</a></li>
|
||||
<li><a href="#oauthauthentication">OAuthAuthentication</a></li>
|
||||
<li><a href="#oauth2authentication">OAuth2Authentication</a></li>
|
||||
<li class="main"><a href="#custom-authentication">Custom authentication</a></li>
|
||||
<li><a href="#example">Example</a></li>
|
||||
<li class="main"><a href="#third-party-packages">Third party packages</a></li>
|
||||
<li><a href="#digest-authentication">Digest Authentication</a></li>
|
||||
<li><a href="#django-oauth-toolkit">Django OAuth Toolkit</a></li>
|
||||
<li><a href="#django-oauth2-consumer">Django OAuth2 Consumer</a></li>
|
||||
<li><a href="#json-web-token-authentication">JSON Web Token Authentication</a></li>
|
||||
<li><a href="#hawk-http-authentication">Hawk HTTP Authentication</a></li>
|
||||
<li><a href="#http-signature-authentication">HTTP Signature Authentication</a></li>
|
||||
<li><a href="#djoser">Djoser</a></li>
|
||||
|
||||
<div class="promo">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#authentication">Authentication</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#how-authentication-is-determined">How authentication is determined</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#setting-the-authentication-scheme">Setting the authentication scheme</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#unauthorized-and-forbidden-responses">Unauthorized and Forbidden responses</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#apache-mod_wsgi-specific-configuration">Apache mod_wsgi specific configuration</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#api-reference">API Reference</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#basicauthentication">BasicAuthentication</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#tokenauthentication">TokenAuthentication</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#sessionauthentication">SessionAuthentication</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#oauthauthentication">OAuthAuthentication</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#oauth2authentication">OAuth2Authentication</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#custom-authentication">Custom authentication</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#example">Example</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#third-party-packages">Third party packages</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#digest-authentication">Digest Authentication</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#django-oauth-toolkit">Django OAuth Toolkit</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#django-oauth2-consumer">Django OAuth2 Consumer</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#json-web-token-authentication">JSON Web Token Authentication</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#hawk-http-authentication">Hawk HTTP Authentication</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#http-signature-authentication">HTTP Signature Authentication</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#djoser">Djoser</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
<p><a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/authentication.py"><span class="label label-info">authentication.py</span></a></p>
|
||||
<h1 id="authentication">Authentication</h1>
|
||||
|
||||
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/authentication.py">
|
||||
<span class="label label-info">authentication.py</span>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<h1 id="authentication">Authentication</h1>
|
||||
<blockquote>
|
||||
<p>Auth needs to be pluggable.</p>
|
||||
<p>— Jacob Kaplan-Moss, <a href="http://jacobian.org/writing/rest-worst-practices/">"REST worst practices"</a></p>
|
||||
</blockquote>
|
||||
<p>Authentication is the mechanism of associating an incoming request with a set of identifying credentials, such as the user the request came from, or the token that it was signed with. The <a href="permissions">permission</a> and <a href="throttling">throttling</a> policies can then use those credentials to determine if the request should be permitted.</p>
|
||||
<p>Authentication is the mechanism of associating an incoming request with a set of identifying credentials, such as the user the request came from, or the token that it was signed with. The <a href="../permissions">permission</a> and <a href="../throttling">throttling</a> policies can then use those credentials to determine if the request should be permitted.</p>
|
||||
<p>REST framework provides a number of authentication schemes out of the box, and also allows you to implement custom schemes.</p>
|
||||
<p>Authentication is always run at the very start of the view, before the permission and throttling checks occur, and before any other code is allowed to proceed.</p>
|
||||
<p>The <code>request.user</code> property will typically be set to an instance of the <code>contrib.auth</code> package's <code>User</code> class.</p>
|
||||
<p>The <code>request.auth</code> property is used for any additional authentication information, for example, it may be used to represent an authentication token that the request was signed with.</p>
|
||||
<hr />
|
||||
<p><strong>Note:</strong> Don't forget that <strong>authentication by itself won't allow or disallow an incoming request</strong>, it simply identifies the credentials that the request was made with.</p>
|
||||
<p>For information on how to setup the permission polices for your API please see the <a href="permissions">permissions documentation</a>.</p>
|
||||
<p>For information on how to setup the permission polices for your API please see the <a href="../permissions">permissions documentation</a>.</p>
|
||||
<hr />
|
||||
<h2 id="how-authentication-is-determined">How authentication is determined</h2>
|
||||
<p>The authentication schemes are always defined as a list of classes. REST framework will attempt to authenticate with each class in the list, and will set <code>request.user</code> and <code>request.auth</code> using the return value of the first class that successfully authenticates.</p>
|
||||
|
|
@ -238,7 +476,7 @@ a.fusion-poweredby {
|
|||
<p>The value of <code>request.user</code> and <code>request.auth</code> for unauthenticated requests can be modified using the <code>UNAUTHENTICATED_USER</code> and <code>UNAUTHENTICATED_TOKEN</code> settings.</p>
|
||||
<h2 id="setting-the-authentication-scheme">Setting the authentication scheme</h2>
|
||||
<p>The default authentication schemes may be set globally, using the <code>DEFAULT_AUTHENTICATION</code> setting. For example.</p>
|
||||
<pre class="prettyprint lang-py"><code>REST_FRAMEWORK = {
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.BasicAuthentication',
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
|
|
@ -247,7 +485,7 @@ a.fusion-poweredby {
|
|||
</code></pre>
|
||||
<p>You can also set the authentication scheme on a per-view or per-viewset basis,
|
||||
using the <code>APIView</code> class based views.</p>
|
||||
<pre class="prettyprint lang-py"><code>from rest_framework.authentication import SessionAuthentication, BasicAuthentication
|
||||
<pre><code>from rest_framework.authentication import SessionAuthentication, BasicAuthentication
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
|
@ -264,7 +502,7 @@ class ExampleView(APIView):
|
|||
return Response(content)
|
||||
</code></pre>
|
||||
<p>Or, if you're using the <code>@api_view</code> decorator with function based views.</p>
|
||||
<pre class="prettyprint lang-py"><code>@api_view(['GET'])
|
||||
<pre><code>@api_view(['GET'])
|
||||
@authentication_classes((SessionAuthentication, BasicAuthentication))
|
||||
@permission_classes((IsAuthenticated,))
|
||||
def example_view(request, format=None):
|
||||
|
|
@ -286,7 +524,7 @@ def example_view(request, format=None):
|
|||
<h2 id="apache-mod_wsgi-specific-configuration">Apache mod_wsgi specific configuration</h2>
|
||||
<p>Note that if deploying to <a href="http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIPassAuthorization">Apache using mod_wsgi</a>, the authorization header is not passed through to a WSGI application by default, as it is assumed that authentication will be handled by Apache, rather than at an application level.</p>
|
||||
<p>If you are deploying to Apache, and using any non-session based authentication, you will need to explicitly configure mod_wsgi to pass the required headers through to the application. This can be done by specifying the <code>WSGIPassAuthorization</code> directive in the appropriate context and setting it to <code>'On'</code>.</p>
|
||||
<pre class="prettyprint lang-py"><code># this can go in either server config, virtual host, directory or .htaccess
|
||||
<pre><code># this can go in either server config, virtual host, directory or .htaccess
|
||||
WSGIPassAuthorization On
|
||||
</code></pre>
|
||||
<hr />
|
||||
|
|
@ -299,13 +537,13 @@ WSGIPassAuthorization On
|
|||
<li><code>request.auth</code> will be <code>None</code>.</li>
|
||||
</ul>
|
||||
<p>Unauthenticated responses that are denied permission will result in an <code>HTTP 401 Unauthorized</code> response with an appropriate WWW-Authenticate header. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>WWW-Authenticate: Basic realm="api"
|
||||
<pre><code>WWW-Authenticate: Basic realm="api"
|
||||
</code></pre>
|
||||
<p><strong>Note:</strong> If you use <code>BasicAuthentication</code> in production you must ensure that your API is only available over <code>https</code>. You should also ensure that your API clients will always re-request the username and password at login, and will never store those details to persistent storage.</p>
|
||||
<h2 id="tokenauthentication">TokenAuthentication</h2>
|
||||
<p>This authentication scheme uses a simple token-based HTTP Authentication scheme. Token authentication is appropriate for client-server setups, such as native desktop and mobile clients.</p>
|
||||
<p>To use the <code>TokenAuthentication</code> scheme you'll need to <a href="#setting-the-authentication-scheme">configure the authentication classes</a> to include <code>TokenAuthentication</code>, and additionally include <code>rest_framework.authtoken</code> in your <code>INSTALLED_APPS</code> setting:</p>
|
||||
<pre class="prettyprint lang-py"><code>INSTALLED_APPS = (
|
||||
<pre><code>INSTALLED_APPS = (
|
||||
...
|
||||
'rest_framework.authtoken'
|
||||
)
|
||||
|
|
@ -314,13 +552,13 @@ WSGIPassAuthorization On
|
|||
<p><strong>Note:</strong> Make sure to run <code>manage.py syncdb</code> after changing your settings. The <code>rest_framework.authtoken</code> app provides both Django (from v1.7) and South database migrations. See <a href="#schema-migrations">Schema migrations</a> below.</p>
|
||||
<hr />
|
||||
<p>You'll also need to create tokens for your users.</p>
|
||||
<pre class="prettyprint lang-py"><code>from rest_framework.authtoken.models import Token
|
||||
<pre><code>from rest_framework.authtoken.models import Token
|
||||
|
||||
token = Token.objects.create(user=...)
|
||||
print token.key
|
||||
</code></pre>
|
||||
<p>For clients to authenticate, the token key should be included in the <code>Authorization</code> HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
|
||||
<pre><code>Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
|
||||
</code></pre>
|
||||
<p>If successfully authenticated, <code>TokenAuthentication</code> provides the following credentials.</p>
|
||||
<ul>
|
||||
|
|
@ -328,17 +566,17 @@ print token.key
|
|||
<li><code>request.auth</code> will be a <code>rest_framework.authtoken.models.BasicToken</code> instance.</li>
|
||||
</ul>
|
||||
<p>Unauthenticated responses that are denied permission will result in an <code>HTTP 401 Unauthorized</code> response with an appropriate WWW-Authenticate header. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>WWW-Authenticate: Token
|
||||
<pre><code>WWW-Authenticate: Token
|
||||
</code></pre>
|
||||
<p>The <code>curl</code> command line tool may be useful for testing token authenticated APIs. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
|
||||
<pre><code>curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
|
||||
</code></pre>
|
||||
<hr />
|
||||
<p><strong>Note:</strong> If you use <code>TokenAuthentication</code> in production you must ensure that your API is only available over <code>https</code>.</p>
|
||||
<hr />
|
||||
<h4 id="generating-tokens">Generating Tokens</h4>
|
||||
<p>If you want every user to have an automatically generated Token, you can simply catch the User's <code>post_save</code> signal.</p>
|
||||
<pre class="prettyprint lang-py"><code>from django.conf import settings
|
||||
<pre><code>from django.conf import settings
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
|
|
@ -351,21 +589,21 @@ def create_auth_token(sender, instance=None, created=False, **kwargs):
|
|||
</code></pre>
|
||||
<p>Note that you'll want to ensure you place this code snippet in an installed <code>models.py</code> module, or some other location that will be imported by Django on startup.</p>
|
||||
<p>If you've already created some users, you can generate tokens for all existing users like this:</p>
|
||||
<pre class="prettyprint lang-py"><code>from django.contrib.auth.models import User
|
||||
<pre><code>from django.contrib.auth.models import User
|
||||
from rest_framework.authtoken.models import Token
|
||||
|
||||
for user in User.objects.all():
|
||||
Token.objects.get_or_create(user=user)
|
||||
</code></pre>
|
||||
<p>When using <code>TokenAuthentication</code>, you may want to provide a mechanism for clients to obtain a token given the username and password. REST framework provides a built-in view to provide this behavior. To use it, add the <code>obtain_auth_token</code> view to your URLconf:</p>
|
||||
<pre class="prettyprint lang-py"><code>from rest_framework.authtoken import views
|
||||
<pre><code>from rest_framework.authtoken import views
|
||||
urlpatterns += [
|
||||
url(r'^api-token-auth/', views.obtain_auth_token)
|
||||
]
|
||||
</code></pre>
|
||||
<p>Note that the URL part of the pattern can be whatever you want to use.</p>
|
||||
<p>The <code>obtain_auth_token</code> view will return a JSON response when valid <code>username</code> and <code>password</code> fields are POSTed to the view using form data or JSON:</p>
|
||||
<pre class="prettyprint lang-py"><code>{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
|
||||
<pre><code>{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
|
||||
</code></pre>
|
||||
<p>Note that the default <code>obtain_auth_token</code> view explicitly uses JSON requests and responses, rather than using default renderer and parser classes in your settings. If you need a customized version of the <code>obtain_auth_token</code> view, you can do so by overriding the <code>ObtainAuthToken</code> view class, and using that in your url conf instead.</p>
|
||||
<h4 id="schema-migrations">Schema migrations</h4>
|
||||
|
|
@ -375,7 +613,7 @@ urlpatterns += [
|
|||
<hr />
|
||||
<p>If you're using a <a href="https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model">custom user model</a> you'll need to make sure that any initial migration that creates the user table runs before the authtoken table is created.</p>
|
||||
<p>You can do so by inserting a <code>needed_by</code> attribute in your user migration:</p>
|
||||
<pre class="prettyprint lang-py"><code>class Migration:
|
||||
<pre><code>class Migration:
|
||||
|
||||
needed_by = (
|
||||
('authtoken', '0001_initial'),
|
||||
|
|
@ -386,7 +624,7 @@ urlpatterns += [
|
|||
</code></pre>
|
||||
<p>For more details, see the <a href="http://south.readthedocs.org/en/latest/dependencies.html">south documentation on dependencies</a>.</p>
|
||||
<p>Also note that if you're using a <code>post_save</code> signal to create tokens, then the first time you create the database tables, you'll need to ensure any migrations are run prior to creating any superusers. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>python manage.py syncdb --noinput # Won't create a superuser just yet, due to `--noinput`.
|
||||
<pre><code>python manage.py syncdb --noinput # Won't create a superuser just yet, due to `--noinput`.
|
||||
python manage.py migrate
|
||||
python manage.py createsuperuser
|
||||
</code></pre>
|
||||
|
|
@ -402,13 +640,13 @@ python manage.py createsuperuser
|
|||
<h2 id="oauthauthentication">OAuthAuthentication</h2>
|
||||
<p>This authentication uses <a href="http://oauth.net/core/1.0a">OAuth 1.0a</a> authentication scheme. OAuth 1.0a provides signature validation which provides a reasonable level of security over plain non-HTTPS connections. However, it may also be considered more complicated than OAuth2, as it requires clients to sign their requests.</p>
|
||||
<p>This authentication class depends on the optional <code>django-oauth-plus</code> and <code>oauth2</code> packages. In order to make it work you must install these packages and add <code>oauth_provider</code> to your <code>INSTALLED_APPS</code>:</p>
|
||||
<pre class="prettyprint lang-py"><code>INSTALLED_APPS = (
|
||||
<pre><code>INSTALLED_APPS = (
|
||||
...
|
||||
`oauth_provider`,
|
||||
)
|
||||
</code></pre>
|
||||
<p>Don't forget to run <code>syncdb</code> once you've added the package.</p>
|
||||
<pre class="prettyprint lang-py"><code>python manage.py syncdb
|
||||
<pre><code>python manage.py syncdb
|
||||
</code></pre>
|
||||
<h4 id="getting-started-with-django-oauth-plus">Getting started with django-oauth-plus</h4>
|
||||
<p>The OAuthAuthentication class only provides token verification and signature validation for requests. It doesn't provide authorization flow for your clients. You still need to implement your own views for accessing and authorizing tokens.</p>
|
||||
|
|
@ -416,23 +654,23 @@ python manage.py createsuperuser
|
|||
<h2 id="oauth2authentication">OAuth2Authentication</h2>
|
||||
<p>This authentication uses <a href="http://tools.ietf.org/html/rfc6749">OAuth 2.0</a> authentication scheme. OAuth2 is more simple to work with than OAuth1, and provides much better security than simple token authentication. It is an unauthenticated scheme, and requires you to use an HTTPS connection.</p>
|
||||
<p>This authentication class depends on the optional <a href="https://github.com/caffeinehit/django-oauth2-provider">django-oauth2-provider</a> project. In order to make it work you must install this package and add <code>provider</code> and <code>provider.oauth2</code> to your <code>INSTALLED_APPS</code>:</p>
|
||||
<pre class="prettyprint lang-py"><code>INSTALLED_APPS = (
|
||||
<pre><code>INSTALLED_APPS = (
|
||||
...
|
||||
'provider',
|
||||
'provider.oauth2',
|
||||
)
|
||||
</code></pre>
|
||||
<p>Then add <code>OAuth2Authentication</code> to your global <code>DEFAULT_AUTHENTICATION</code> setting:</p>
|
||||
<pre class="prettyprint lang-py"><code>'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
<pre><code>'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.OAuth2Authentication',
|
||||
),
|
||||
</code></pre>
|
||||
<p>You must also include the following in your root <code>urls.py</code> module:</p>
|
||||
<pre class="prettyprint lang-py"><code>url(r'^oauth2/', include('provider.oauth2.urls', namespace='oauth2')),
|
||||
<pre><code>url(r'^oauth2/', include('provider.oauth2.urls', namespace='oauth2')),
|
||||
</code></pre>
|
||||
<p>Note that the <code>namespace='oauth2'</code> argument is required.</p>
|
||||
<p>Finally, sync your database.</p>
|
||||
<pre class="prettyprint lang-py"><code>python manage.py syncdb
|
||||
<pre><code>python manage.py syncdb
|
||||
python manage.py migrate
|
||||
</code></pre>
|
||||
<hr />
|
||||
|
|
@ -454,15 +692,15 @@ python manage.py migrate
|
|||
<li><code>password</code> well, that speaks for itself.</li>
|
||||
</ul>
|
||||
<p>You can use the command line to test that your local configuration is working:</p>
|
||||
<pre class="prettyprint lang-py"><code>curl -X POST -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=password&username=YOUR_USERNAME&password=YOUR_PASSWORD" http://localhost:8000/oauth2/access_token/
|
||||
<pre><code>curl -X POST -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=password&username=YOUR_USERNAME&password=YOUR_PASSWORD" http://localhost:8000/oauth2/access_token/
|
||||
</code></pre>
|
||||
<p>You should get a response that looks something like this:</p>
|
||||
<pre class="prettyprint lang-py"><code>{"access_token": "<your-access-token>", "scope": "read", "expires_in": 86399, "refresh_token": "<your-refresh-token>"}
|
||||
<pre><code>{"access_token": "<your-access-token>", "scope": "read", "expires_in": 86399, "refresh_token": "<your-refresh-token>"}
|
||||
</code></pre>
|
||||
<h5 id="3-access-the-api">3. Access the API</h5>
|
||||
<p>The only thing needed to make the <code>OAuth2Authentication</code> class work is to insert the <code>access_token</code> you've received in the <code>Authorization</code> request header.</p>
|
||||
<p>The command line to test the authentication looks like:</p>
|
||||
<pre class="prettyprint lang-py"><code>curl -H "Authorization: Bearer <your-access-token>" http://localhost:8000/api/
|
||||
<pre><code>curl -H "Authorization: Bearer <your-access-token>" http://localhost:8000/api/
|
||||
</code></pre>
|
||||
<h3 id="alternative-oauth-2-implementations">Alternative OAuth 2 implementations</h3>
|
||||
<p>Note that <a href="https://github.com/evonove/django-oauth-toolkit">Django OAuth Toolkit</a> is an alternative external package that also includes OAuth 2.0 support for REST framework.</p>
|
||||
|
|
@ -479,7 +717,7 @@ python manage.py migrate
|
|||
<p>If the <code>.authenticate_header()</code> method is not overridden, the authentication scheme will return <code>HTTP 403 Forbidden</code> responses when an unauthenticated request is denied access.</p>
|
||||
<h2 id="example">Example</h2>
|
||||
<p>The following example will authenticate any incoming request as the user given by the username in a custom request header named 'X_USERNAME'.</p>
|
||||
<pre class="prettyprint lang-py"><code>from django.contrib.auth.models import User
|
||||
<pre><code>from django.contrib.auth.models import User
|
||||
from rest_framework import authentication
|
||||
from rest_framework import exceptions
|
||||
|
||||
|
|
@ -502,7 +740,7 @@ class ExampleAuthentication(authentication.BaseAuthentication):
|
|||
<h2 id="digest-authentication">Digest Authentication</h2>
|
||||
<p>HTTP digest authentication is a widely implemented scheme that was intended to replace HTTP basic authentication, and which provides a simple encrypted authentication mechanism. <a href="https://github.com/juanriaza">Juan Riaza</a> maintains the <a href="https://github.com/juanriaza/django-rest-framework-digestauth">djangorestframework-digestauth</a> package which provides HTTP digest authentication support for REST framework.</p>
|
||||
<h2 id="django-oauth-toolkit">Django OAuth Toolkit</h2>
|
||||
<p>The <a href="https://github.com/evonove/django-oauth-toolkit">Django OAuth Toolkit</a> package provides OAuth 2.0 support, and works with Python 2.7 and Python 3.3+. The package is maintained by <a href="https://github.com/evonove/">Evonove</a> and uses the excelllent <a href="https://github.com/idan/oauthlib">OAuthLib</a>. The package is well documented, and comes as a recommended alternative for OAuth 2.0 support.</p>
|
||||
<p>The <a href="https://github.com/evonove/django-oauth-toolkit">Django OAuth Toolkit</a> package provides OAuth 2.0 support, and works with Python 2.7 and Python 3.3+. The package is maintained by <a href="https://github.com/evonove/">Evonove</a> and uses the excellent <a href="https://github.com/idan/oauthlib">OAuthLib</a>. The package is well documented, and comes as a recommended alternative for OAuth 2.0 support.</p>
|
||||
<h2 id="django-oauth2-consumer">Django OAuth2 Consumer</h2>
|
||||
<p>The <a href="https://github.com/Rediker-Software/doac">Django OAuth2 Consumer</a> library from <a href="https://github.com/Rediker-Software">Rediker Software</a> is another package that provides <a href="https://github.com/Rediker-Software/doac/blob/master/docs/integrations.md#">OAuth 2.0 support for REST framework</a>. The package includes token scoping permissions on tokens, which allows finer-grained access to your API.</p>
|
||||
<h2 id="json-web-token-authentication">JSON Web Token Authentication</h2>
|
||||
|
|
@ -513,42 +751,52 @@ class ExampleAuthentication(authentication.BaseAuthentication):
|
|||
<p>HTTP Signature (currently a <a href="https://datatracker.ietf.org/doc/draft-cavage-http-signatures/">IETF draft</a>) provides a way to achieve origin authentication and message integrity for HTTP messages. Similar to <a href="http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html">Amazon's HTTP Signature scheme</a>, used by many of its services, it permits stateless, per-request authentication. <a href="https://github.com/etoccalino/">Elvio Toccalino</a> maintains the <a href="https://github.com/etoccalino/django-rest-framework-httpsignature">djangorestframework-httpsignature</a> package which provides an easy to use HTTP Signature Authentication mechanism.</p>
|
||||
<h2 id="djoser">Djoser</h2>
|
||||
<p><a href="https://github.com/sunscrapers/djoser">Djoser</a> library provides a set of views to handle basic actions such as registration, login, logout, password reset and account activation. The package works with a custom user model and it uses token based authentication. This is a ready to use REST implementation of Django authentication system.</p>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
</div>
|
||||
<!--/span-->
|
||||
</div>
|
||||
<!--/row-->
|
||||
</div>
|
||||
<!--/.fluid-container-->
|
||||
</div>
|
||||
<!--/.body content-->
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
<!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://www.django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="../../js/jquery-1.8.1-min.js"></script>
|
||||
<script src="../../js/prettify-1.0.js"></script>
|
||||
<script src="../../js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
</html>
|
||||
|
|
@ -1,315 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Content negotiation - Django REST framework</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/content-negotiation"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Content negotiation, Custom content negotiation">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="content-negotiation-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/format-suffixes">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/pagination"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/third-party-resources">Third Party Resources</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/contributing">Contributing to REST framework</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.4-announcement">2.4 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/kickstarter-announcement">Kickstarter Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<!-- TODO
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Version: 2.0.0 <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Trunk</a></li>
|
||||
<li><a href="#">2.0.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span3">
|
||||
<!-- TODO
|
||||
<p style="margin-top: -12px">
|
||||
<a class="btn btn-mini btn-primary" style="width: 60px">« previous</a>
|
||||
<a class="btn btn-mini btn-primary" style="float: right; margin-right: 8px; width: 60px;">next »</a>
|
||||
</p>
|
||||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
<li class="main"><a href="#content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="#determining-the-accepted-renderer">Determining the accepted renderer</a></li>
|
||||
<li class="main"><a href="#custom-content-negotiation">Custom content negotiation</a></li>
|
||||
<li><a href="#example">Example</a></li>
|
||||
<li><a href="#setting-the-content-negotiation">Setting the content negotiation</a></li>
|
||||
|
||||
<div class="promo">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
<p><a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/negotiation.py"><span class="label label-info">negotiation.py</span></a></p>
|
||||
<h1 id="content-negotiation">Content negotiation</h1>
|
||||
<blockquote>
|
||||
<p>HTTP has provisions for several mechanisms for "content negotiation" - the process of selecting the best representation for a given response when there are multiple representations available.</p>
|
||||
<p>— <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html">RFC 2616</a>, Fielding et al.</p>
|
||||
</blockquote>
|
||||
<p>Content negotiation is the process of selecting one of multiple possible representations to return to a client, based on client or server preferences.</p>
|
||||
<h2 id="determining-the-accepted-renderer">Determining the accepted renderer</h2>
|
||||
<p>REST framework uses a simple style of content negotiation to determine which media type should be returned to a client, based on the available renderers, the priorities of each of those renderers, and the client's <code>Accept:</code> header. The style used is partly client-driven, and partly server-driven.</p>
|
||||
<ol>
|
||||
<li>More specific media types are given preference to less specific media types.</li>
|
||||
<li>If multiple media types have the same specificity, then preference is given to based on the ordering of the renderers configured for the given view.</li>
|
||||
</ol>
|
||||
<p>For example, given the following <code>Accept</code> header:</p>
|
||||
<pre class="prettyprint lang-py"><code>application/json; indent=4, application/json, application/yaml, text/html, */*
|
||||
</code></pre>
|
||||
<p>The priorities for each of the given media types would be:</p>
|
||||
<ul>
|
||||
<li><code>application/json; indent=4</code></li>
|
||||
<li><code>application/json</code>, <code>application/yaml</code> and <code>text/html</code></li>
|
||||
<li><code>*/*</code></li>
|
||||
</ul>
|
||||
<p>If the requested view was only configured with renderers for <code>YAML</code> and <code>HTML</code>, then REST framework would select whichever renderer was listed first in the <code>renderer_classes</code> list or <code>DEFAULT_RENDERER_CLASSES</code> setting.</p>
|
||||
<p>For more information on the <code>HTTP Accept</code> header, see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">RFC 2616</a> </p>
|
||||
<hr />
|
||||
<p><strong>Note</strong>: "q" values are not taken into account by REST framework when determining preference. The use of "q" values negatively impacts caching, and in the author's opinion they are an unnecessary and overcomplicated approach to content negotiation.</p>
|
||||
<p>This is a valid approach as the HTTP spec deliberately underspecifies how a server should weight server-based preferences against client-based preferences.</p>
|
||||
<hr />
|
||||
<h1 id="custom-content-negotiation">Custom content negotiation</h1>
|
||||
<p>It's unlikely that you'll want to provide a custom content negotiation scheme for REST framework, but you can do so if needed. To implement a custom content negotiation scheme override <code>BaseContentNegotiation</code>.</p>
|
||||
<p>REST framework's content negotiation classes handle selection of both the appropriate parser for the request, and the appropriate renderer for the response, so you should implement both the <code>.select_parser(request, parsers)</code> and <code>.select_renderer(request, renderers, format_suffix)</code> methods.</p>
|
||||
<p>The <code>select_parser()</code> method should return one of the parser instances from the list of available parsers, or <code>None</code> if none of the parsers can handle the incoming request.</p>
|
||||
<p>The <code>select_renderer()</code> method should return a two-tuple of (renderer instance, media type), or raise a <code>NotAcceptable</code> exception.</p>
|
||||
<h2 id="example">Example</h2>
|
||||
<p>The following is a custom content negotiation class which ignores the client
|
||||
request when selecting the appropriate parser or renderer.</p>
|
||||
<pre class="prettyprint lang-py"><code>from rest_framework.negotiation import BaseContentNegotiation
|
||||
|
||||
class IgnoreClientContentNegotiation(BaseContentNegotiation):
|
||||
def select_parser(self, request, parsers):
|
||||
"""
|
||||
Select the first parser in the `.parser_classes` list.
|
||||
"""
|
||||
return parsers[0]
|
||||
|
||||
def select_renderer(self, request, renderers, format_suffix):
|
||||
"""
|
||||
Select the first renderer in the `.renderer_classes` list.
|
||||
"""
|
||||
return (renderers[0], renderers[0].media_type)
|
||||
</code></pre>
|
||||
<h2 id="setting-the-content-negotiation">Setting the content negotiation</h2>
|
||||
<p>The default content negotiation class may be set globally, using the <code>DEFAULT_CONTENT_NEGOTIATION_CLASS</code> setting. For example, the following settings would use our example <code>IgnoreClientContentNegotiation</code> class.</p>
|
||||
<pre class="prettyprint lang-py"><code>REST_FRAMEWORK = {
|
||||
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'myapp.negotiation.IgnoreClientContentNegotiation',
|
||||
}
|
||||
</code></pre>
|
||||
<p>You can also set the content negotiation used for an individual view, or viewset, using the <code>APIView</code> class based views.</p>
|
||||
<pre class="prettyprint lang-py"><code>from myapp.negotiation import IgnoreClientContentNegotiation
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
class NoNegotiationView(APIView):
|
||||
"""
|
||||
An example view that does not perform content negotiation.
|
||||
"""
|
||||
content_negotiation_class = IgnoreClientContentNegotiation
|
||||
|
||||
def get(self, request, format=None):
|
||||
return Response({
|
||||
'accepted media type': request.accepted_renderer.media_type
|
||||
})
|
||||
</code></pre>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://www.django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
507
api-guide/content-negotiation/index.html
Normal file
507
api-guide/content-negotiation/index.html
Normal file
|
|
@ -0,0 +1,507 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Content negotiation - Django REST framework</title>
|
||||
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/content-negotiation/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Content negotiation">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="../../css/prettify.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="../../css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../format-suffixes">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../pagination">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li ><a href="/">Home</a></li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/quickstart">Quickstart</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/1-serialization">1 - Serialization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/2-requests-and-responses">2 - Requests and responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/3-class-based-views">3 - Class based views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/6-viewsets-and-routers">6- Viewsets and routers</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../requests">Requests</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../responses">Responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../views">Views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../generic-views">Generic views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../viewsets">Viewsets</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../routers">Routers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../parsers">Parsers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../renderers">Renderers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../serializers">Serializers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../fields">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../relations">Serializer relations</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../validators">Validators</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../authentication">Authentication</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../permissions">Permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../throttling">Throttling</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../filtering">Filtering</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../pagination">Pagination</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href=".">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../format-suffixes">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../reverse">Returning URLs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../exceptions">Exceptions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../status-codes">Status codes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../testing">Testing</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../settings">Settings</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../../topics/documenting-your-api">Documenting your API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/ajax-csrf-cors">AJAX, CSRF & CORS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browser-enhancements">Browser enhancements</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browsable-api">The Browsable API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/third-party-resources">Third Party Resources</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/contributing">Contributing to REST framework</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-framework-2-announcement">2.0 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.2-announcement">2.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.3-announcement">2.3 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.4-announcement">2.4 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/release-notes">Release Notes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/credits">Credits</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span3">
|
||||
<!-- TODO
|
||||
<p style="margin-top: -12px">
|
||||
<a class="btn btn-mini btn-primary" style="width: 60px">« previous</a>
|
||||
<a class="btn btn-mini btn-primary" style="float: right; margin-right: 8px; width: 60px;">next »</a>
|
||||
</p>
|
||||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#content-negotiation">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#determining-the-accepted-renderer">Determining the accepted renderer</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#custom-content-negotiation">Custom content negotiation</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#example">Example</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#setting-the-content-negotiation">Setting the content negotiation</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
|
||||
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/negotiation.py">
|
||||
<span class="label label-info">negotiation.py</span>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<h1 id="content-negotiation">Content negotiation</h1>
|
||||
<blockquote>
|
||||
<p>HTTP has provisions for several mechanisms for "content negotiation" - the process of selecting the best representation for a given response when there are multiple representations available.</p>
|
||||
<p>— <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html">RFC 2616</a>, Fielding et al.</p>
|
||||
</blockquote>
|
||||
<p>Content negotiation is the process of selecting one of multiple possible representations to return to a client, based on client or server preferences.</p>
|
||||
<h2 id="determining-the-accepted-renderer">Determining the accepted renderer</h2>
|
||||
<p>REST framework uses a simple style of content negotiation to determine which media type should be returned to a client, based on the available renderers, the priorities of each of those renderers, and the client's <code>Accept:</code> header. The style used is partly client-driven, and partly server-driven.</p>
|
||||
<ol>
|
||||
<li>More specific media types are given preference to less specific media types.</li>
|
||||
<li>If multiple media types have the same specificity, then preference is given to based on the ordering of the renderers configured for the given view.</li>
|
||||
</ol>
|
||||
<p>For example, given the following <code>Accept</code> header:</p>
|
||||
<pre><code>application/json; indent=4, application/json, application/yaml, text/html, */*
|
||||
</code></pre>
|
||||
<p>The priorities for each of the given media types would be:</p>
|
||||
<ul>
|
||||
<li><code>application/json; indent=4</code></li>
|
||||
<li><code>application/json</code>, <code>application/yaml</code> and <code>text/html</code></li>
|
||||
<li><code>*/*</code></li>
|
||||
</ul>
|
||||
<p>If the requested view was only configured with renderers for <code>YAML</code> and <code>HTML</code>, then REST framework would select whichever renderer was listed first in the <code>renderer_classes</code> list or <code>DEFAULT_RENDERER_CLASSES</code> setting.</p>
|
||||
<p>For more information on the <code>HTTP Accept</code> header, see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">RFC 2616</a></p>
|
||||
<hr />
|
||||
<p><strong>Note</strong>: "q" values are not taken into account by REST framework when determining preference. The use of "q" values negatively impacts caching, and in the author's opinion they are an unnecessary and overcomplicated approach to content negotiation.</p>
|
||||
<p>This is a valid approach as the HTTP spec deliberately underspecifies how a server should weight server-based preferences against client-based preferences.</p>
|
||||
<hr />
|
||||
<h1 id="custom-content-negotiation">Custom content negotiation</h1>
|
||||
<p>It's unlikely that you'll want to provide a custom content negotiation scheme for REST framework, but you can do so if needed. To implement a custom content negotiation scheme override <code>BaseContentNegotiation</code>.</p>
|
||||
<p>REST framework's content negotiation classes handle selection of both the appropriate parser for the request, and the appropriate renderer for the response, so you should implement both the <code>.select_parser(request, parsers)</code> and <code>.select_renderer(request, renderers, format_suffix)</code> methods.</p>
|
||||
<p>The <code>select_parser()</code> method should return one of the parser instances from the list of available parsers, or <code>None</code> if none of the parsers can handle the incoming request.</p>
|
||||
<p>The <code>select_renderer()</code> method should return a two-tuple of (renderer instance, media type), or raise a <code>NotAcceptable</code> exception.</p>
|
||||
<h2 id="example">Example</h2>
|
||||
<p>The following is a custom content negotiation class which ignores the client
|
||||
request when selecting the appropriate parser or renderer.</p>
|
||||
<pre><code>from rest_framework.negotiation import BaseContentNegotiation
|
||||
|
||||
class IgnoreClientContentNegotiation(BaseContentNegotiation):
|
||||
def select_parser(self, request, parsers):
|
||||
"""
|
||||
Select the first parser in the `.parser_classes` list.
|
||||
"""
|
||||
return parsers[0]
|
||||
|
||||
def select_renderer(self, request, renderers, format_suffix):
|
||||
"""
|
||||
Select the first renderer in the `.renderer_classes` list.
|
||||
"""
|
||||
return (renderers[0], renderers[0].media_type)
|
||||
</code></pre>
|
||||
<h2 id="setting-the-content-negotiation">Setting the content negotiation</h2>
|
||||
<p>The default content negotiation class may be set globally, using the <code>DEFAULT_CONTENT_NEGOTIATION_CLASS</code> setting. For example, the following settings would use our example <code>IgnoreClientContentNegotiation</code> class.</p>
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'myapp.negotiation.IgnoreClientContentNegotiation',
|
||||
}
|
||||
</code></pre>
|
||||
<p>You can also set the content negotiation used for an individual view, or viewset, using the <code>APIView</code> class based views.</p>
|
||||
<pre><code>from myapp.negotiation import IgnoreClientContentNegotiation
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
class NoNegotiationView(APIView):
|
||||
"""
|
||||
An example view that does not perform content negotiation.
|
||||
"""
|
||||
content_negotiation_class = IgnoreClientContentNegotiation
|
||||
|
||||
def get(self, request, format=None):
|
||||
return Response({
|
||||
'accepted media type': request.accepted_renderer.media_type
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
<!--/span-->
|
||||
</div>
|
||||
<!--/row-->
|
||||
</div>
|
||||
<!--/.fluid-container-->
|
||||
</div>
|
||||
<!--/.body content-->
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
<!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="../../js/jquery-1.8.1-min.js"></script>
|
||||
<script src="../../js/prettify-1.0.js"></script>
|
||||
<script src="../../js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,352 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Exceptions - Django REST framework</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/exceptions"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Exceptions, API Reference">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="exceptions-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/status-codes">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/reverse"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/third-party-resources">Third Party Resources</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/contributing">Contributing to REST framework</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.4-announcement">2.4 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/kickstarter-announcement">Kickstarter Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<!-- TODO
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Version: 2.0.0 <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Trunk</a></li>
|
||||
<li><a href="#">2.0.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span3">
|
||||
<!-- TODO
|
||||
<p style="margin-top: -12px">
|
||||
<a class="btn btn-mini btn-primary" style="width: 60px">« previous</a>
|
||||
<a class="btn btn-mini btn-primary" style="float: right; margin-right: 8px; width: 60px;">next »</a>
|
||||
</p>
|
||||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
<li class="main"><a href="#exceptions">Exceptions</a></li>
|
||||
<li><a href="#exception-handling-in-rest-framework-views">Exception handling in REST framework views</a></li>
|
||||
<li><a href="#custom-exception-handling">Custom exception handling</a></li>
|
||||
<li class="main"><a href="#api-reference">API Reference</a></li>
|
||||
<li><a href="#apiexception">APIException</a></li>
|
||||
<li><a href="#parseerror">ParseError</a></li>
|
||||
<li><a href="#authenticationfailed">AuthenticationFailed</a></li>
|
||||
<li><a href="#notauthenticated">NotAuthenticated</a></li>
|
||||
<li><a href="#permissiondenied">PermissionDenied</a></li>
|
||||
<li><a href="#methodnotallowed">MethodNotAllowed</a></li>
|
||||
<li><a href="#unsupportedmediatype">UnsupportedMediaType</a></li>
|
||||
<li><a href="#throttled">Throttled</a></li>
|
||||
|
||||
<div class="promo">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
<p><a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/exceptions.py"><span class="label label-info">exceptions.py</span></a></p>
|
||||
<h1 id="exceptions">Exceptions</h1>
|
||||
<blockquote>
|
||||
<p>Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure.</p>
|
||||
<p>— Doug Hellmann, <a href="http://www.doughellmann.com/articles/how-tos/python-exception-handling/index.html">Python Exception Handling Techniques</a></p>
|
||||
</blockquote>
|
||||
<h2 id="exception-handling-in-rest-framework-views">Exception handling in REST framework views</h2>
|
||||
<p>REST framework's views handle various exceptions, and deal with returning appropriate error responses.</p>
|
||||
<p>The handled exceptions are:</p>
|
||||
<ul>
|
||||
<li>Subclasses of <code>APIException</code> raised inside REST framework.</li>
|
||||
<li>Django's <code>Http404</code> exception.</li>
|
||||
<li>Django's <code>PermissionDenied</code> exception.</li>
|
||||
</ul>
|
||||
<p>In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.</p>
|
||||
<p>By default all error responses will include a key <code>detail</code> in the body of the response, but other keys may also be included.</p>
|
||||
<p>For example, the following request:</p>
|
||||
<pre class="prettyprint lang-py"><code>DELETE http://api.example.com/foo/bar HTTP/1.1
|
||||
Accept: application/json
|
||||
</code></pre>
|
||||
<p>Might receive an error response indicating that the <code>DELETE</code> method is not allowed on that resource:</p>
|
||||
<pre class="prettyprint lang-py"><code>HTTP/1.1 405 Method Not Allowed
|
||||
Content-Type: application/json
|
||||
Content-Length: 42
|
||||
|
||||
{"detail": "Method 'DELETE' not allowed."}
|
||||
</code></pre>
|
||||
<h2 id="custom-exception-handling">Custom exception handling</h2>
|
||||
<p>You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.</p>
|
||||
<p>The function must take a single argument, which is the exception to be handled, and should either return a <code>Response</code> object, or return <code>None</code> if the exception cannot be handled. If the handler returns <code>None</code> then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.</p>
|
||||
<p>For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:</p>
|
||||
<pre class="prettyprint lang-py"><code>HTTP/1.1 405 Method Not Allowed
|
||||
Content-Type: application/json
|
||||
Content-Length: 62
|
||||
|
||||
{"status_code": 405, "detail": "Method 'DELETE' not allowed."}
|
||||
</code></pre>
|
||||
<p>In order to alter the style of the response, you could write the following custom exception handler:</p>
|
||||
<pre class="prettyprint lang-py"><code>from rest_framework.views import exception_handler
|
||||
|
||||
def custom_exception_handler(exc):
|
||||
# Call REST framework's default exception handler first,
|
||||
# to get the standard error response.
|
||||
response = exception_handler(exc)
|
||||
|
||||
# Now add the HTTP status code to the response.
|
||||
if response is not None:
|
||||
response.data['status_code'] = response.status_code
|
||||
|
||||
return response
|
||||
</code></pre>
|
||||
<p>The exception handler must also be configured in your settings, using the <code>EXCEPTION_HANDLER</code> setting key. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>REST_FRAMEWORK = {
|
||||
'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
|
||||
}
|
||||
</code></pre>
|
||||
<p>If not specified, the <code>'EXCEPTION_HANDLER'</code> setting defaults to the standard exception handler provided by REST framework:</p>
|
||||
<pre class="prettyprint lang-py"><code>REST_FRAMEWORK = {
|
||||
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
|
||||
}
|
||||
</code></pre>
|
||||
<p>Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the <code>HTTP_400_BAD_REQUEST</code> responses that are returned by the generic views when serializer validation fails.</p>
|
||||
<hr />
|
||||
<h1 id="api-reference">API Reference</h1>
|
||||
<h2 id="apiexception">APIException</h2>
|
||||
<p><strong>Signature:</strong> <code>APIException()</code></p>
|
||||
<p>The <strong>base class</strong> for all exceptions raised inside an <code>APIView</code> class or <code>@api_view</code>.</p>
|
||||
<p>To provide a custom exception, subclass <code>APIException</code> and set the <code>.status_code</code> and <code>.default_detail</code> properties on the class.</p>
|
||||
<p>For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the "503 Service Unavailable" HTTP response code. You could do this like so:</p>
|
||||
<pre class="prettyprint lang-py"><code>from rest_framework.exceptions import APIException
|
||||
|
||||
class ServiceUnavailable(APIException):
|
||||
status_code = 503
|
||||
default_detail = 'Service temporarily unavailable, try again later.'
|
||||
</code></pre>
|
||||
<h2 id="parseerror">ParseError</h2>
|
||||
<p><strong>Signature:</strong> <code>ParseError(detail=None)</code></p>
|
||||
<p>Raised if the request contains malformed data when accessing <code>request.DATA</code> or <code>request.FILES</code>.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "400 Bad Request".</p>
|
||||
<h2 id="authenticationfailed">AuthenticationFailed</h2>
|
||||
<p><strong>Signature:</strong> <code>AuthenticationFailed(detail=None)</code></p>
|
||||
<p>Raised when an incoming request includes incorrect authentication.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the <a href="authentication">authentication documentation</a> for more details.</p>
|
||||
<h2 id="notauthenticated">NotAuthenticated</h2>
|
||||
<p><strong>Signature:</strong> <code>NotAuthenticated(detail=None)</code></p>
|
||||
<p>Raised when an unauthenticated request fails the permission checks.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the <a href="authentication">authentication documentation</a> for more details.</p>
|
||||
<h2 id="permissiondenied">PermissionDenied</h2>
|
||||
<p><strong>Signature:</strong> <code>PermissionDenied(detail=None)</code></p>
|
||||
<p>Raised when an authenticated request fails the permission checks.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "403 Forbidden".</p>
|
||||
<h2 id="methodnotallowed">MethodNotAllowed</h2>
|
||||
<p><strong>Signature:</strong> <code>MethodNotAllowed(method, detail=None)</code></p>
|
||||
<p>Raised when an incoming request occurs that does not map to a handler method on the view.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "405 Method Not Allowed".</p>
|
||||
<h2 id="unsupportedmediatype">UnsupportedMediaType</h2>
|
||||
<p><strong>Signature:</strong> <code>UnsupportedMediaType(media_type, detail=None)</code></p>
|
||||
<p>Raised if there are no parsers that can handle the content type of the request data when accessing <code>request.DATA</code> or <code>request.FILES</code>.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "415 Unsupported Media Type".</p>
|
||||
<h2 id="throttled">Throttled</h2>
|
||||
<p><strong>Signature:</strong> <code>Throttled(wait=None, detail=None)</code></p>
|
||||
<p>Raised when an incoming request fails the throttling checks.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "429 Too Many Requests".</p>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://www.django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
565
api-guide/exceptions/index.html
Normal file
565
api-guide/exceptions/index.html
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Exceptions - Django REST framework</title>
|
||||
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/exceptions/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Exceptions">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="../../css/prettify.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="../../css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../status-codes">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../reverse">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li ><a href="/">Home</a></li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/quickstart">Quickstart</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/1-serialization">1 - Serialization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/2-requests-and-responses">2 - Requests and responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/3-class-based-views">3 - Class based views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/6-viewsets-and-routers">6- Viewsets and routers</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../requests">Requests</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../responses">Responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../views">Views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../generic-views">Generic views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../viewsets">Viewsets</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../routers">Routers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../parsers">Parsers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../renderers">Renderers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../serializers">Serializers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../fields">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../relations">Serializer relations</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../validators">Validators</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../authentication">Authentication</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../permissions">Permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../throttling">Throttling</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../filtering">Filtering</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../pagination">Pagination</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../content-negotiation">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../format-suffixes">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../reverse">Returning URLs</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href=".">Exceptions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../status-codes">Status codes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../testing">Testing</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../settings">Settings</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../../topics/documenting-your-api">Documenting your API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/ajax-csrf-cors">AJAX, CSRF & CORS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browser-enhancements">Browser enhancements</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browsable-api">The Browsable API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/third-party-resources">Third Party Resources</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/contributing">Contributing to REST framework</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-framework-2-announcement">2.0 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.2-announcement">2.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.3-announcement">2.3 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.4-announcement">2.4 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/release-notes">Release Notes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/credits">Credits</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span3">
|
||||
<!-- TODO
|
||||
<p style="margin-top: -12px">
|
||||
<a class="btn btn-mini btn-primary" style="width: 60px">« previous</a>
|
||||
<a class="btn btn-mini btn-primary" style="float: right; margin-right: 8px; width: 60px;">next »</a>
|
||||
</p>
|
||||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#exceptions">Exceptions</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#exception-handling-in-rest-framework-views">Exception handling in REST framework views</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#custom-exception-handling">Custom exception handling</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#api-reference">API Reference</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#apiexception">APIException</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#parseerror">ParseError</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#authenticationfailed">AuthenticationFailed</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#notauthenticated">NotAuthenticated</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#permissiondenied">PermissionDenied</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#methodnotallowed">MethodNotAllowed</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#unsupportedmediatype">UnsupportedMediaType</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#throttled">Throttled</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
|
||||
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/exceptions.py">
|
||||
<span class="label label-info">exceptions.py</span>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<h1 id="exceptions">Exceptions</h1>
|
||||
<blockquote>
|
||||
<p>Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure.</p>
|
||||
<p>— Doug Hellmann, <a href="http://www.doughellmann.com/articles/how-tos/python-exception-handling/index.html">Python Exception Handling Techniques</a></p>
|
||||
</blockquote>
|
||||
<h2 id="exception-handling-in-rest-framework-views">Exception handling in REST framework views</h2>
|
||||
<p>REST framework's views handle various exceptions, and deal with returning appropriate error responses.</p>
|
||||
<p>The handled exceptions are:</p>
|
||||
<ul>
|
||||
<li>Subclasses of <code>APIException</code> raised inside REST framework.</li>
|
||||
<li>Django's <code>Http404</code> exception.</li>
|
||||
<li>Django's <code>PermissionDenied</code> exception.</li>
|
||||
</ul>
|
||||
<p>In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.</p>
|
||||
<p>By default all error responses will include a key <code>detail</code> in the body of the response, but other keys may also be included.</p>
|
||||
<p>For example, the following request:</p>
|
||||
<pre><code>DELETE http://api.example.com/foo/bar HTTP/1.1
|
||||
Accept: application/json
|
||||
</code></pre>
|
||||
<p>Might receive an error response indicating that the <code>DELETE</code> method is not allowed on that resource:</p>
|
||||
<pre><code>HTTP/1.1 405 Method Not Allowed
|
||||
Content-Type: application/json
|
||||
Content-Length: 42
|
||||
|
||||
{"detail": "Method 'DELETE' not allowed."}
|
||||
</code></pre>
|
||||
<h2 id="custom-exception-handling">Custom exception handling</h2>
|
||||
<p>You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.</p>
|
||||
<p>The function must take a single argument, which is the exception to be handled, and should either return a <code>Response</code> object, or return <code>None</code> if the exception cannot be handled. If the handler returns <code>None</code> then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.</p>
|
||||
<p>For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:</p>
|
||||
<pre><code>HTTP/1.1 405 Method Not Allowed
|
||||
Content-Type: application/json
|
||||
Content-Length: 62
|
||||
|
||||
{"status_code": 405, "detail": "Method 'DELETE' not allowed."}
|
||||
</code></pre>
|
||||
<p>In order to alter the style of the response, you could write the following custom exception handler:</p>
|
||||
<pre><code>from rest_framework.views import exception_handler
|
||||
|
||||
def custom_exception_handler(exc):
|
||||
# Call REST framework's default exception handler first,
|
||||
# to get the standard error response.
|
||||
response = exception_handler(exc)
|
||||
|
||||
# Now add the HTTP status code to the response.
|
||||
if response is not None:
|
||||
response.data['status_code'] = response.status_code
|
||||
|
||||
return response
|
||||
</code></pre>
|
||||
<p>The exception handler must also be configured in your settings, using the <code>EXCEPTION_HANDLER</code> setting key. For example:</p>
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
|
||||
}
|
||||
</code></pre>
|
||||
<p>If not specified, the <code>'EXCEPTION_HANDLER'</code> setting defaults to the standard exception handler provided by REST framework:</p>
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
|
||||
}
|
||||
</code></pre>
|
||||
<p>Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the <code>HTTP_400_BAD_REQUEST</code> responses that are returned by the generic views when serializer validation fails.</p>
|
||||
<hr />
|
||||
<h1 id="api-reference">API Reference</h1>
|
||||
<h2 id="apiexception">APIException</h2>
|
||||
<p><strong>Signature:</strong> <code>APIException()</code></p>
|
||||
<p>The <strong>base class</strong> for all exceptions raised inside an <code>APIView</code> class or <code>@api_view</code>.</p>
|
||||
<p>To provide a custom exception, subclass <code>APIException</code> and set the <code>.status_code</code> and <code>.default_detail</code> properties on the class.</p>
|
||||
<p>For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the "503 Service Unavailable" HTTP response code. You could do this like so:</p>
|
||||
<pre><code>from rest_framework.exceptions import APIException
|
||||
|
||||
class ServiceUnavailable(APIException):
|
||||
status_code = 503
|
||||
default_detail = 'Service temporarily unavailable, try again later.'
|
||||
</code></pre>
|
||||
<h2 id="parseerror">ParseError</h2>
|
||||
<p><strong>Signature:</strong> <code>ParseError(detail=None)</code></p>
|
||||
<p>Raised if the request contains malformed data when accessing <code>request.DATA</code> or <code>request.FILES</code>.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "400 Bad Request".</p>
|
||||
<h2 id="authenticationfailed">AuthenticationFailed</h2>
|
||||
<p><strong>Signature:</strong> <code>AuthenticationFailed(detail=None)</code></p>
|
||||
<p>Raised when an incoming request includes incorrect authentication.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the <a href="../authentication">authentication documentation</a> for more details.</p>
|
||||
<h2 id="notauthenticated">NotAuthenticated</h2>
|
||||
<p><strong>Signature:</strong> <code>NotAuthenticated(detail=None)</code></p>
|
||||
<p>Raised when an unauthenticated request fails the permission checks.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the <a href="../authentication">authentication documentation</a> for more details.</p>
|
||||
<h2 id="permissiondenied">PermissionDenied</h2>
|
||||
<p><strong>Signature:</strong> <code>PermissionDenied(detail=None)</code></p>
|
||||
<p>Raised when an authenticated request fails the permission checks.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "403 Forbidden".</p>
|
||||
<h2 id="methodnotallowed">MethodNotAllowed</h2>
|
||||
<p><strong>Signature:</strong> <code>MethodNotAllowed(method, detail=None)</code></p>
|
||||
<p>Raised when an incoming request occurs that does not map to a handler method on the view.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "405 Method Not Allowed".</p>
|
||||
<h2 id="unsupportedmediatype">UnsupportedMediaType</h2>
|
||||
<p><strong>Signature:</strong> <code>UnsupportedMediaType(media_type, detail=None)</code></p>
|
||||
<p>Raised if there are no parsers that can handle the content type of the request data when accessing <code>request.DATA</code> or <code>request.FILES</code>.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "415 Unsupported Media Type".</p>
|
||||
<h2 id="throttled">Throttled</h2>
|
||||
<p><strong>Signature:</strong> <code>Throttled(wait=None, detail=None)</code></p>
|
||||
<p>Raised when an incoming request fails the throttling checks.</p>
|
||||
<p>By default this exception results in a response with the HTTP status code "429 Too Many Requests".</p>
|
||||
|
||||
</div>
|
||||
<!--/span-->
|
||||
</div>
|
||||
<!--/row-->
|
||||
</div>
|
||||
<!--/.fluid-container-->
|
||||
</div>
|
||||
<!--/.body content-->
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
<!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="../../js/jquery-1.8.1-min.js"></script>
|
||||
<script src="../../js/prettify-1.0.js"></script>
|
||||
<script src="../../js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,65 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Serializer fields - Django REST framework</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/fields"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Serializer fields, Generic Fields, Typed Fields, Custom fields, Third party packages">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Serializer fields - Django REST framework</title>
|
||||
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/fields/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Serializer fields">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<!-- Le styles -->
|
||||
<link href="../../css/prettify.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="../../css/default.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="fields-page">
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/relations">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/serializers"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../relations">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../serializers">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
|
|
@ -67,80 +76,218 @@ a.fusion-poweredby {
|
|||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li ><a href="/">Home</a></li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/quickstart">Quickstart</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/1-serialization">1 - Serialization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/2-requests-and-responses">2 - Requests and responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/3-class-based-views">3 - Class based views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/6-viewsets-and-routers">6- Viewsets and routers</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../requests">Requests</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../responses">Responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../views">Views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../generic-views">Generic views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../viewsets">Viewsets</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../routers">Routers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../parsers">Parsers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../renderers">Renderers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../serializers">Serializers</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href=".">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../relations">Serializer relations</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../validators">Validators</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../authentication">Authentication</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../permissions">Permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../throttling">Throttling</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../filtering">Filtering</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../pagination">Pagination</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../content-negotiation">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../format-suffixes">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../reverse">Returning URLs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../exceptions">Exceptions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../status-codes">Status codes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../testing">Testing</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../settings">Settings</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/third-party-resources">Third Party Resources</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/contributing">Contributing to REST framework</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.4-announcement">2.4 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/kickstarter-announcement">Kickstarter Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/documenting-your-api">Documenting your API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/ajax-csrf-cors">AJAX, CSRF & CORS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browser-enhancements">Browser enhancements</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browsable-api">The Browsable API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/third-party-resources">Third Party Resources</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/contributing">Contributing to REST framework</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-framework-2-announcement">2.0 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.2-announcement">2.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.3-announcement">2.3 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.4-announcement">2.4 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/release-notes">Release Notes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/credits">Credits</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<!-- TODO
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Version: 2.0.0 <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Trunk</a></li>
|
||||
<li><a href="#">2.0.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -148,32 +295,34 @@ a.fusion-poweredby {
|
|||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
|
|
@ -186,48 +335,168 @@ a.fusion-poweredby {
|
|||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
<li class="main"><a href="#serializer-fields">Serializer fields</a></li>
|
||||
<li><a href="#core-arguments">Core arguments</a></li>
|
||||
<li class="main"><a href="#generic-fields">Generic Fields</a></li>
|
||||
<li><a href="#field">Field</a></li>
|
||||
<li><a href="#writablefield">WritableField</a></li>
|
||||
<li><a href="#modelfield">ModelField</a></li>
|
||||
<li><a href="#serializermethodfield">SerializerMethodField</a></li>
|
||||
<li class="main"><a href="#typed-fields">Typed Fields</a></li>
|
||||
<li><a href="#booleanfield">BooleanField</a></li>
|
||||
<li><a href="#charfield">CharField</a></li>
|
||||
<li><a href="#urlfield">URLField</a></li>
|
||||
<li><a href="#slugfield">SlugField</a></li>
|
||||
<li><a href="#choicefield">ChoiceField</a></li>
|
||||
<li><a href="#emailfield">EmailField</a></li>
|
||||
<li><a href="#regexfield">RegexField</a></li>
|
||||
<li><a href="#datetimefield">DateTimeField</a></li>
|
||||
<li><a href="#datefield">DateField</a></li>
|
||||
<li><a href="#timefield">TimeField</a></li>
|
||||
<li><a href="#integerfield">IntegerField</a></li>
|
||||
<li><a href="#floatfield">FloatField</a></li>
|
||||
<li><a href="#decimalfield">DecimalField</a></li>
|
||||
<li><a href="#filefield">FileField</a></li>
|
||||
<li><a href="#imagefield">ImageField</a></li>
|
||||
<li class="main"><a href="#custom-fields">Custom fields</a></li>
|
||||
<li><a href="#examples">Examples</a></li>
|
||||
<li class="main"><a href="#third-party-packages">Third party packages</a></li>
|
||||
<li><a href="#drf-compound-fields">DRF Compound Fields</a></li>
|
||||
<li><a href="#drf-extra-fields">DRF Extra Fields</a></li>
|
||||
<li><a href="#django-rest-framework-gis">django-rest-framework-gis</a></li>
|
||||
<li><a href="#django-rest-framework-hstore">django-rest-framework-hstore</a></li>
|
||||
|
||||
<div class="promo">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#serializer-fields">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#core-arguments">Core arguments</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#generic-fields">Generic Fields</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#field">Field</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#writablefield">WritableField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#modelfield">ModelField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#serializermethodfield">SerializerMethodField</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#typed-fields">Typed Fields</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#booleanfield">BooleanField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#charfield">CharField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#urlfield">URLField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#slugfield">SlugField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#choicefield">ChoiceField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#emailfield">EmailField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#regexfield">RegexField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#datetimefield">DateTimeField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#datefield">DateField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#timefield">TimeField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#integerfield">IntegerField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#floatfield">FloatField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#decimalfield">DecimalField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#filefield">FileField</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#imagefield">ImageField</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#custom-fields">Custom fields</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#examples">Examples</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#third-party-packages">Third party packages</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#drf-compound-fields">DRF Compound Fields</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#drf-extra-fields">DRF Extra Fields</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#django-rest-framework-gis">django-rest-framework-gis</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#django-rest-framework-hstore">django-rest-framework-hstore</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
<p><a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/fields.py"><span class="label label-info">fields.py</span></a></p>
|
||||
<h1 id="serializer-fields">Serializer fields</h1>
|
||||
|
||||
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/fields.py">
|
||||
<span class="label label-info">fields.py</span>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<h1 id="serializer-fields">Serializer fields</h1>
|
||||
<blockquote>
|
||||
<p>Each field in a Form class is responsible not only for validating data, but also for "cleaning" it — normalizing it to a consistent format.</p>
|
||||
<p>— <a href="https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.cleaned_data">Django documentation</a></p>
|
||||
|
|
@ -261,7 +530,7 @@ Set to false if this field is not required to be present during deserialization.
|
|||
<p>A dictionary of error codes to error messages.</p>
|
||||
<h3 id="widget"><code>widget</code></h3>
|
||||
<p>Used only if rendering the field to HTML.
|
||||
This argument sets the widget that should be used to render the field. For more details, and a list of available widgets, see <a href="https://docs.djangoproject.com/en/dev/ref/forms/widgets/">the Django documentation on form widgets</a>. </p>
|
||||
This argument sets the widget that should be used to render the field. For more details, and a list of available widgets, see <a href="https://docs.djangoproject.com/en/dev/ref/forms/widgets/">the Django documentation on form widgets</a>.</p>
|
||||
<h3 id="label"><code>label</code></h3>
|
||||
<p>A short text string that may be used as the name of the field in HTML form fields or other descriptive elements.</p>
|
||||
<h3 id="help_text"><code>help_text</code></h3>
|
||||
|
|
@ -272,7 +541,7 @@ This argument sets the widget that should be used to render the field. For more
|
|||
<h2 id="field">Field</h2>
|
||||
<p>A generic, <strong>read-only</strong> field. You can use this field for any attribute that does not need to support write operations.</p>
|
||||
<p>For example, using the following model.</p>
|
||||
<pre class="prettyprint lang-py"><code>from django.db import models
|
||||
<pre><code>from django.db import models
|
||||
from django.utils.timezone import now
|
||||
|
||||
class Account(models.Model):
|
||||
|
|
@ -285,7 +554,7 @@ class Account(models.Model):
|
|||
return now() > self.payment_expiry
|
||||
</code></pre>
|
||||
<p>A serializer definition that looked like this:</p>
|
||||
<pre class="prettyprint lang-py"><code>from rest_framework import serializers
|
||||
<pre><code>from rest_framework import serializers
|
||||
|
||||
class AccountSerializer(serializers.HyperlinkedModelSerializer):
|
||||
expired = serializers.Field(source='has_expired')
|
||||
|
|
@ -295,7 +564,7 @@ class AccountSerializer(serializers.HyperlinkedModelSerializer):
|
|||
fields = ('url', 'owner', 'name', 'expired')
|
||||
</code></pre>
|
||||
<p>Would produce output similar to:</p>
|
||||
<pre class="prettyprint lang-py"><code>{
|
||||
<pre><code>{
|
||||
'url': 'http://example.com/api/accounts/3/',
|
||||
'owner': 'http://example.com/api/users/12/',
|
||||
'name': 'FooCorp business account',
|
||||
|
|
@ -312,7 +581,7 @@ class AccountSerializer(serializers.HyperlinkedModelSerializer):
|
|||
<p><strong>Signature:</strong> <code>ModelField(model_field=<Django ModelField instance>)</code></p>
|
||||
<h2 id="serializermethodfield">SerializerMethodField</h2>
|
||||
<p>This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object. The field's constructor accepts a single argument, which is the name of the method on the serializer to be called. The method should accept a single argument (in addition to <code>self</code>), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>from django.contrib.auth.models import User
|
||||
<pre><code>from django.contrib.auth.models import User
|
||||
from django.utils.timezone import now
|
||||
from rest_framework import serializers
|
||||
|
||||
|
|
@ -359,7 +628,7 @@ or <code>django.db.models.fields.TextField</code>.</p>
|
|||
<p>Corresponds to <code>django.db.models.fields.DateTimeField</code></p>
|
||||
<p>When using <code>ModelSerializer</code> or <code>HyperlinkedModelSerializer</code>, note that any model fields with <code>auto_now=True</code> or <code>auto_now_add=True</code> will use serializer fields that are <code>read_only=True</code> by default.</p>
|
||||
<p>If you want to override this behavior, you'll need to declare the <code>DateTimeField</code> explicitly on the serializer. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>class CommentSerializer(serializers.ModelSerializer):
|
||||
<pre><code>class CommentSerializer(serializers.ModelSerializer):
|
||||
created = serializers.DateTimeField()
|
||||
|
||||
class Meta:
|
||||
|
|
@ -399,7 +668,25 @@ or <code>django.db.models.fields.TextField</code>.</p>
|
|||
<p>A floating point representation.</p>
|
||||
<p>Corresponds to <code>django.db.models.fields.FloatField</code>.</p>
|
||||
<h2 id="decimalfield">DecimalField</h2>
|
||||
<p>A decimal representation.</p>
|
||||
<p>A decimal representation, represented in Python by a Decimal instance.</p>
|
||||
<p>Has two required arguments:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>max_digits</code> The maximum number of digits allowed in the number. Note that this number must be greater than or equal to decimal_places.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>decimal_places</code> The number of decimal places to store with the number.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>For example, to validate numbers up to 999 with a resolution of 2 decimal places, you would use:</p>
|
||||
<pre><code>serializers.DecimalField(max_digits=5, decimal_places=2)
|
||||
</code></pre>
|
||||
<p>And to validate numbers up to anything less than one billion with a resolution of 10 decimal places:</p>
|
||||
<pre><code>serializers.DecimalField(max_digits=19, decimal_places=10)
|
||||
</code></pre>
|
||||
<p>This field also takes an optional argument, <code>coerce_to_string</code>. If set to <code>True</code> the representation will be output as a string. If set to <code>False</code> the representation will be left as a <code>Decimal</code> instance and the final representation will be determined by the renderer.</p>
|
||||
<p>If unset, this will default to the same value as the <code>COERCE_DECIMAL_TO_STRING</code> setting, which is <code>True</code> unless set otherwise.</p>
|
||||
<p><strong>Signature:</strong> <code>DecimalField(max_digits, decimal_places, coerce_to_string=None)</code></p>
|
||||
<p>Corresponds to <code>django.db.models.fields.DecimalField</code>.</p>
|
||||
<h2 id="filefield">FileField</h2>
|
||||
<p>A file representation. Performs Django's standard FileField validation.</p>
|
||||
|
|
@ -427,7 +714,7 @@ Django's regular <a href="https://docs.djangoproject.com/en/dev/ref/settings/#st
|
|||
<p>The <code>.to_native()</code> method is called to convert the initial datatype into a primitive, serializable datatype. The <code>from_native()</code> method is called to restore a primitive datatype into its initial representation.</p>
|
||||
<h2 id="examples">Examples</h2>
|
||||
<p>Let's look at an example of serializing a class that represents an RGB color value:</p>
|
||||
<pre class="prettyprint lang-py"><code>class Color(object):
|
||||
<pre><code>class Color(object):
|
||||
"""
|
||||
A color represented in the RGB colorspace.
|
||||
"""
|
||||
|
|
@ -450,7 +737,7 @@ class ColourField(serializers.WritableField):
|
|||
</code></pre>
|
||||
<p>By default field values are treated as mapping to an attribute on the object. If you need to customize how the field value is accessed and set you need to override <code>.field_to_native()</code> and/or <code>.field_from_native()</code>.</p>
|
||||
<p>As an example, let's create a field that can be used represent the class name of the object being serialized:</p>
|
||||
<pre class="prettyprint lang-py"><code>class ClassNameField(serializers.Field):
|
||||
<pre><code>class ClassNameField(serializers.Field):
|
||||
def field_to_native(self, obj, field_name):
|
||||
"""
|
||||
Serialize the object's class name.
|
||||
|
|
@ -467,42 +754,52 @@ class ColourField(serializers.WritableField):
|
|||
<p>The <a href="https://github.com/djangonauts/django-rest-framework-gis">django-rest-framework-gis</a> package provides geographic addons for django rest framework like a <code>GeometryField</code> field and a GeoJSON serializer.</p>
|
||||
<h2 id="django-rest-framework-hstore">django-rest-framework-hstore</h2>
|
||||
<p>The <a href="https://github.com/djangonauts/django-rest-framework-hstore">django-rest-framework-hstore</a> package provides an <code>HStoreField</code> to support <a href="https://github.com/djangonauts/django-hstore">django-hstore</a> <code>DictionaryField</code> model field.</p>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
</div>
|
||||
<!--/span-->
|
||||
</div>
|
||||
<!--/row-->
|
||||
</div>
|
||||
<!--/.fluid-container-->
|
||||
</div>
|
||||
<!--/.body content-->
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
<!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://www.django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="../../js/jquery-1.8.1-min.js"></script>
|
||||
<script src="../../js/prettify-1.0.js"></script>
|
||||
<script src="../../js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
</html>
|
||||
|
|
@ -1,65 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Filtering - Django REST framework</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/filtering"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Filtering, Generic Filtering, API Guide, Custom generic filtering, Third party packages">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Filtering - Django REST framework</title>
|
||||
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/filtering/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Filtering">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<!-- Le styles -->
|
||||
<link href="../../css/prettify.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="../../css/default.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="filtering-page">
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/pagination">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/throttling"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../pagination">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../throttling">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
|
|
@ -67,80 +76,218 @@ a.fusion-poweredby {
|
|||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li ><a href="/">Home</a></li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/quickstart">Quickstart</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/1-serialization">1 - Serialization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/2-requests-and-responses">2 - Requests and responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/3-class-based-views">3 - Class based views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/6-viewsets-and-routers">6- Viewsets and routers</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../requests">Requests</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../responses">Responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../views">Views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../generic-views">Generic views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../viewsets">Viewsets</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../routers">Routers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../parsers">Parsers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../renderers">Renderers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../serializers">Serializers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../fields">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../relations">Serializer relations</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../validators">Validators</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../authentication">Authentication</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../permissions">Permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../throttling">Throttling</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href=".">Filtering</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../pagination">Pagination</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../content-negotiation">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../format-suffixes">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../reverse">Returning URLs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../exceptions">Exceptions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../status-codes">Status codes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../testing">Testing</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../settings">Settings</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/third-party-resources">Third Party Resources</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/contributing">Contributing to REST framework</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.4-announcement">2.4 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/kickstarter-announcement">Kickstarter Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/documenting-your-api">Documenting your API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/ajax-csrf-cors">AJAX, CSRF & CORS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browser-enhancements">Browser enhancements</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browsable-api">The Browsable API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/third-party-resources">Third Party Resources</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/contributing">Contributing to REST framework</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-framework-2-announcement">2.0 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.2-announcement">2.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.3-announcement">2.3 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.4-announcement">2.4 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/release-notes">Release Notes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/credits">Credits</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<!-- TODO
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Version: 2.0.0 <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Trunk</a></li>
|
||||
<li><a href="#">2.0.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -148,32 +295,34 @@ a.fusion-poweredby {
|
|||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
|
|
@ -186,35 +335,116 @@ a.fusion-poweredby {
|
|||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
<li class="main"><a href="#filtering">Filtering</a></li>
|
||||
<li><a href="#filtering-against-the-current-user">Filtering against the current user</a></li>
|
||||
<li><a href="#filtering-against-the-url">Filtering against the URL</a></li>
|
||||
<li><a href="#filtering-against-query-parameters">Filtering against query parameters</a></li>
|
||||
<li class="main"><a href="#generic-filtering">Generic Filtering</a></li>
|
||||
<li><a href="#setting-filter-backends">Setting filter backends</a></li>
|
||||
<li><a href="#filtering-and-object-lookups">Filtering and object lookups</a></li>
|
||||
<li><a href="#overriding-the-initial-queryset">Overriding the initial queryset</a></li>
|
||||
<li class="main"><a href="#api-guide">API Guide</a></li>
|
||||
<li><a href="#djangofilterbackend">DjangoFilterBackend</a></li>
|
||||
<li><a href="#searchfilter">SearchFilter</a></li>
|
||||
<li><a href="#orderingfilter">OrderingFilter</a></li>
|
||||
<li><a href="#djangoobjectpermissionsfilter">DjangoObjectPermissionsFilter</a></li>
|
||||
<li class="main"><a href="#custom-generic-filtering">Custom generic filtering</a></li>
|
||||
<li><a href="#example">Example</a></li>
|
||||
<li class="main"><a href="#third-party-packages">Third party packages</a></li>
|
||||
<li><a href="#django-rest-framework-chain">Django REST framework chain</a></li>
|
||||
|
||||
<div class="promo">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#filtering">Filtering</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#filtering-against-the-current-user">Filtering against the current user</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#filtering-against-the-url">Filtering against the URL</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#filtering-against-query-parameters">Filtering against query parameters</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#generic-filtering">Generic Filtering</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#setting-filter-backends">Setting filter backends</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#filtering-and-object-lookups">Filtering and object lookups</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#overriding-the-initial-queryset">Overriding the initial queryset</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#api-guide">API Guide</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#djangofilterbackend">DjangoFilterBackend</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#searchfilter">SearchFilter</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#orderingfilter">OrderingFilter</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#djangoobjectpermissionsfilter">DjangoObjectPermissionsFilter</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#custom-generic-filtering">Custom generic filtering</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#example">Example</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#third-party-packages">Third party packages</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#django-rest-framework-chain">Django REST framework chain</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
<p><a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/filters.py"><span class="label label-info">filters.py</span></a></p>
|
||||
<h1 id="filtering">Filtering</h1>
|
||||
|
||||
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/filters.py">
|
||||
<span class="label label-info">filters.py</span>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<h1 id="filtering">Filtering</h1>
|
||||
<blockquote>
|
||||
<p>The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects.</p>
|
||||
<p>— <a href="https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters">Django documentation</a></p>
|
||||
|
|
@ -226,7 +456,7 @@ a.fusion-poweredby {
|
|||
<p>You might want to filter the queryset to ensure that only results relevant to the currently authenticated user making the request are returned.</p>
|
||||
<p>You can do so by filtering based on the value of <code>request.user</code>.</p>
|
||||
<p>For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>from myapp.models import Purchase
|
||||
<pre><code>from myapp.models import Purchase
|
||||
from myapp.serializers import PurchaseSerializer
|
||||
from rest_framework import generics
|
||||
|
||||
|
|
@ -242,12 +472,12 @@ class PurchaseList(generics.ListAPIView):
|
|||
return Purchase.objects.filter(purchaser=user)
|
||||
</code></pre>
|
||||
<h2 id="filtering-against-the-url">Filtering against the URL</h2>
|
||||
<p>Another style of filtering might involve restricting the queryset based on some part of the URL. </p>
|
||||
<p>Another style of filtering might involve restricting the queryset based on some part of the URL.</p>
|
||||
<p>For example if your URL config contained an entry like this:</p>
|
||||
<pre class="prettyprint lang-py"><code>url('^purchases/(?P<username>.+)/$', PurchaseList.as_view()),
|
||||
<pre><code>url('^purchases/(?P<username>.+)/$', PurchaseList.as_view()),
|
||||
</code></pre>
|
||||
<p>You could then write a view that returned a purchase queryset filtered by the username portion of the URL:</p>
|
||||
<pre class="prettyprint lang-py"><code>class PurchaseList(generics.ListAPIView):
|
||||
<pre><code>class PurchaseList(generics.ListAPIView):
|
||||
serializer_class = PurchaseSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
|
|
@ -261,7 +491,7 @@ class PurchaseList(generics.ListAPIView):
|
|||
<h2 id="filtering-against-query-parameters">Filtering against query parameters</h2>
|
||||
<p>A final example of filtering the initial queryset would be to determine the initial queryset based on query parameters in the url.</p>
|
||||
<p>We can override <code>.get_queryset()</code> to deal with URLs such as <code>http://example.com/api/purchases?username=denvercoder9</code>, and filter the queryset only if the <code>username</code> parameter is included in the URL:</p>
|
||||
<pre class="prettyprint lang-py"><code>class PurchaseList(generics.ListAPIView):
|
||||
<pre><code>class PurchaseList(generics.ListAPIView):
|
||||
serializer_class = PurchaseSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
|
|
@ -280,13 +510,13 @@ class PurchaseList(generics.ListAPIView):
|
|||
<p>As well as being able to override the default queryset, REST framework also includes support for generic filtering backends that allow you to easily construct complex searches and filters.</p>
|
||||
<h2 id="setting-filter-backends">Setting filter backends</h2>
|
||||
<p>The default filter backends may be set globally, using the <code>DEFAULT_FILTER_BACKENDS</code> setting. For example.</p>
|
||||
<pre class="prettyprint lang-py"><code>REST_FRAMEWORK = {
|
||||
<pre><code>REST_FRAMEWORK = {
|
||||
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
|
||||
}
|
||||
</code></pre>
|
||||
<p>You can also set the filter backends on a per-view, or per-viewset basis,
|
||||
using the <code>GenericAPIView</code> class based views.</p>
|
||||
<pre class="prettyprint lang-py"><code>from django.contrib.auth.models import User
|
||||
<pre><code>from django.contrib.auth.models import User
|
||||
from myapp.serializers import UserSerializer
|
||||
from rest_framework import filters
|
||||
from rest_framework import generics
|
||||
|
|
@ -299,11 +529,11 @@ class UserListView(generics.ListAPIView):
|
|||
<h2 id="filtering-and-object-lookups">Filtering and object lookups</h2>
|
||||
<p>Note that if a filter backend is configured for a view, then as well as being used to filter list views, it will also be used to filter the querysets used for returning a single object.</p>
|
||||
<p>For instance, given the previous example, and a product with an id of <code>4675</code>, the following URL would either return the corresponding object, or return a 404 response, depending on if the filtering conditions were met by the given product instance:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/products/4675/?category=clothing&max_price=10.00
|
||||
<pre><code>http://example.com/api/products/4675/?category=clothing&max_price=10.00
|
||||
</code></pre>
|
||||
<h2 id="overriding-the-initial-queryset">Overriding the initial queryset</h2>
|
||||
<p>Note that you can use both an overridden <code>.get_queryset()</code> and generic filtering together, and everything will work as expected. For example, if <code>Product</code> had a many-to-many relationship with <code>User</code>, named <code>purchase</code>, you might want to write a view like this:</p>
|
||||
<pre class="prettyprint lang-py"><code>class PurchasedProductsList(generics.ListAPIView):
|
||||
<pre><code>class PurchasedProductsList(generics.ListAPIView):
|
||||
"""
|
||||
Return a list of all the products that the authenticated
|
||||
user has ever purchased, with optional filtering.
|
||||
|
|
@ -319,23 +549,23 @@ class UserListView(generics.ListAPIView):
|
|||
<hr />
|
||||
<h1 id="api-guide">API Guide</h1>
|
||||
<h2 id="djangofilterbackend">DjangoFilterBackend</h2>
|
||||
<p>The <code>DjangoFilterBackend</code> class supports highly customizable field filtering, using the <a href="https://github.com/alex/django-filter">django-filter package</a>. </p>
|
||||
<p>The <code>DjangoFilterBackend</code> class supports highly customizable field filtering, using the <a href="https://github.com/alex/django-filter">django-filter package</a>.</p>
|
||||
<p>To use REST framework's <code>DjangoFilterBackend</code>, first install <code>django-filter</code>.</p>
|
||||
<pre class="prettyprint lang-py"><code>pip install django-filter
|
||||
<pre><code>pip install django-filter
|
||||
</code></pre>
|
||||
<h4 id="specifying-filter-fields">Specifying filter fields</h4>
|
||||
<p>If all you need is simple equality-based filtering, you can set a <code>filter_fields</code> attribute on the view, or viewset, listing the set of fields you wish to filter against.</p>
|
||||
<pre class="prettyprint lang-py"><code>class ProductList(generics.ListAPIView):
|
||||
<pre><code>class ProductList(generics.ListAPIView):
|
||||
queryset = Product.objects.all()
|
||||
serializer_class = ProductSerializer
|
||||
filter_fields = ('category', 'in_stock')
|
||||
</code></pre>
|
||||
<p>This will automatically create a <code>FilterSet</code> class for the given fields, and will allow you to make requests such as:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/products?category=clothing&in_stock=True
|
||||
<pre><code>http://example.com/api/products?category=clothing&in_stock=True
|
||||
</code></pre>
|
||||
<h4 id="specifying-a-filterset">Specifying a FilterSet</h4>
|
||||
<p>For more advanced filtering requirements you can specify a <code>FilterSet</code> class that should be used by the view. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>import django_filters
|
||||
<pre><code>import django_filters
|
||||
from myapp.models import Product
|
||||
from myapp.serializers import ProductSerializer
|
||||
from rest_framework import generics
|
||||
|
|
@ -353,12 +583,12 @@ class ProductList(generics.ListAPIView):
|
|||
filter_class = ProductFilter
|
||||
</code></pre>
|
||||
<p>Which will allow you to make requests such as:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/products?category=clothing&max_price=10.00
|
||||
<pre><code>http://example.com/api/products?category=clothing&max_price=10.00
|
||||
</code></pre>
|
||||
<p>You can also span relationships using <code>django-filter</code>, let's assume that each
|
||||
product has foreign key to <code>Manufacturer</code> model, so we create filter that
|
||||
filters using <code>Manufacturer</code> name. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>import django_filters
|
||||
<pre><code>import django_filters
|
||||
from myapp.models import Product
|
||||
from myapp.serializers import ProductSerializer
|
||||
from rest_framework import generics
|
||||
|
|
@ -369,10 +599,10 @@ class ProductFilter(django_filters.FilterSet):
|
|||
fields = ['category', 'in_stock', 'manufacturer__name']
|
||||
</code></pre>
|
||||
<p>This enables us to make queries like:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/products?manufacturer__name=foo
|
||||
<pre><code>http://example.com/api/products?manufacturer__name=foo
|
||||
</code></pre>
|
||||
<p>This is nice, but it exposes the Django's double underscore convention as part of the API. If you instead want to explicitly name the filter argument you can instead explicitly include it on the <code>FilterSet</code> class:</p>
|
||||
<pre class="prettyprint lang-py"><code>import django_filters
|
||||
<pre><code>import django_filters
|
||||
from myapp.models import Product
|
||||
from myapp.serializers import ProductSerializer
|
||||
from rest_framework import generics
|
||||
|
|
@ -385,14 +615,14 @@ class ProductFilter(django_filters.FilterSet):
|
|||
fields = ['category', 'in_stock', 'manufacturer']
|
||||
</code></pre>
|
||||
<p>And now you can execute:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/products?manufacturer=foo
|
||||
<pre><code>http://example.com/api/products?manufacturer=foo
|
||||
</code></pre>
|
||||
<p>For more details on using filter sets see the <a href="https://django-filter.readthedocs.org/en/latest/index.html">django-filter documentation</a>.</p>
|
||||
<hr />
|
||||
<p><strong>Hints & Tips</strong></p>
|
||||
<ul>
|
||||
<li>By default filtering is not enabled. If you want to use <code>DjangoFilterBackend</code> remember to make sure it is installed by using the <code>'DEFAULT_FILTER_BACKENDS'</code> setting.</li>
|
||||
<li>When using boolean fields, you should use the values <code>True</code> and <code>False</code> in the URL query parameters, rather than <code>0</code>, <code>1</code>, <code>true</code> or <code>false</code>. (The allowed boolean values are currently hardwired in Django's <a href="https://github.com/django/django/blob/master/django/forms/widgets.py">NullBooleanSelect implementation</a>.) </li>
|
||||
<li>When using boolean fields, you should use the values <code>True</code> and <code>False</code> in the URL query parameters, rather than <code>0</code>, <code>1</code>, <code>true</code> or <code>false</code>. (The allowed boolean values are currently hardwired in Django's <a href="https://github.com/django/django/blob/master/django/forms/widgets.py">NullBooleanSelect implementation</a>.)</li>
|
||||
<li><code>django-filter</code> supports filtering across relationships, using Django's double-underscore syntax.</li>
|
||||
<li>For Django 1.3 support, make sure to install <code>django-filter</code> version 0.5.4, as later versions drop support for 1.3.</li>
|
||||
</ul>
|
||||
|
|
@ -400,17 +630,17 @@ class ProductFilter(django_filters.FilterSet):
|
|||
<h2 id="searchfilter">SearchFilter</h2>
|
||||
<p>The <code>SearchFilter</code> class supports simple single query parameter based searching, and is based on the <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields">Django admin's search functionality</a>.</p>
|
||||
<p>The <code>SearchFilter</code> class will only be applied if the view has a <code>search_fields</code> attribute set. The <code>search_fields</code> attribute should be a list of names of text type fields on the model, such as <code>CharField</code> or <code>TextField</code>.</p>
|
||||
<pre class="prettyprint lang-py"><code>class UserListView(generics.ListAPIView):
|
||||
<pre><code>class UserListView(generics.ListAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer = UserSerializer
|
||||
filter_backends = (filters.SearchFilter,)
|
||||
search_fields = ('username', 'email')
|
||||
</code></pre>
|
||||
<p>This will allow the client to filter the items in the list by making queries such as:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/users?search=russell
|
||||
<pre><code>http://example.com/api/users?search=russell
|
||||
</code></pre>
|
||||
<p>You can also perform a related lookup on a ForeignKey or ManyToManyField with the lookup API double-underscore notation:</p>
|
||||
<pre class="prettyprint lang-py"><code>search_fields = ('username', 'email', 'profile__profession')
|
||||
<pre><code>search_fields = ('username', 'email', 'profile__profession')
|
||||
</code></pre>
|
||||
<p>By default, searches will use case-insensitive partial matches. The search parameter may contain multiple search terms, which should be whitespace and/or comma separated. If multiple search terms are used then objects will be returned in the list only if all the provided terms are matched.</p>
|
||||
<p>The search behavior may be restricted by prepending various characters to the <code>search_fields</code>.</p>
|
||||
|
|
@ -420,7 +650,7 @@ class ProductFilter(django_filters.FilterSet):
|
|||
<li>'@' Full-text search. (Currently only supported Django's MySQL backend.)</li>
|
||||
</ul>
|
||||
<p>For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>search_fields = ('=username', '=email')
|
||||
<pre><code>search_fields = ('=username', '=email')
|
||||
</code></pre>
|
||||
<p>By default, the search parameter is named <code>'search</code>', but this may be overridden with the <code>SEARCH_PARAM</code> setting.</p>
|
||||
<p>For more details, see the <a href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields">Django documentation</a>.</p>
|
||||
|
|
@ -428,17 +658,17 @@ class ProductFilter(django_filters.FilterSet):
|
|||
<h2 id="orderingfilter">OrderingFilter</h2>
|
||||
<p>The <code>OrderingFilter</code> class supports simple query parameter controlled ordering of results. By default, the query parameter is named <code>'ordering'</code>, but this may by overridden with the <code>ORDERING_PARAM</code> setting.</p>
|
||||
<p>For example, to order users by username:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/users?ordering=username
|
||||
<pre><code>http://example.com/api/users?ordering=username
|
||||
</code></pre>
|
||||
<p>The client may also specify reverse orderings by prefixing the field name with '-', like so:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/users?ordering=-username
|
||||
<pre><code>http://example.com/api/users?ordering=-username
|
||||
</code></pre>
|
||||
<p>Multiple orderings may also be specified:</p>
|
||||
<pre class="prettyprint lang-py"><code>http://example.com/api/users?ordering=account,username
|
||||
<pre><code>http://example.com/api/users?ordering=account,username
|
||||
</code></pre>
|
||||
<h3 id="specifying-which-fields-may-be-ordered-against">Specifying which fields may be ordered against</h3>
|
||||
<p>It's recommended that you explicitly specify which fields the API should allowing in the ordering filter. You can do this by setting an <code>ordering_fields</code> attribute on the view, like so:</p>
|
||||
<pre class="prettyprint lang-py"><code>class UserListView(generics.ListAPIView):
|
||||
<pre><code>class UserListView(generics.ListAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserSerializer
|
||||
filter_backends = (filters.OrderingFilter,)
|
||||
|
|
@ -447,7 +677,7 @@ class ProductFilter(django_filters.FilterSet):
|
|||
<p>This helps prevent unexpected data leakage, such as allowing users to order against a password hash field or other sensitive data.</p>
|
||||
<p>If you <em>don't</em> specify an <code>ordering_fields</code> attribute on the view, the filter class will default to allowing the user to filter on any readable fields on the serializer specified by the <code>serializer_class</code> attribute.</p>
|
||||
<p>If you are confident that the queryset being used by the view doesn't contain any sensitive data, you can also explicitly specify that a view should allow ordering on <em>any</em> model field or queryset aggregate, by using the special value <code>'__all__'</code>.</p>
|
||||
<pre class="prettyprint lang-py"><code>class BookingsListView(generics.ListAPIView):
|
||||
<pre><code>class BookingsListView(generics.ListAPIView):
|
||||
queryset = Booking.objects.all()
|
||||
serializer_class = BookingSerializer
|
||||
filter_backends = (filters.OrderingFilter,)
|
||||
|
|
@ -456,7 +686,7 @@ class ProductFilter(django_filters.FilterSet):
|
|||
<h3 id="specifying-a-default-ordering">Specifying a default ordering</h3>
|
||||
<p>If an <code>ordering</code> attribute is set on the view, this will be used as the default ordering.</p>
|
||||
<p>Typically you'd instead control this by setting <code>order_by</code> on the initial queryset, but using the <code>ordering</code> parameter on the view allows you to specify the ordering in a way that it can then be passed automatically as context to a rendered template. This makes it possible to automatically render column headers differently if they are being used to order the results.</p>
|
||||
<pre class="prettyprint lang-py"><code>class UserListView(generics.ListAPIView):
|
||||
<pre><code>class UserListView(generics.ListAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserSerializer
|
||||
filter_backends = (filters.OrderingFilter,)
|
||||
|
|
@ -470,7 +700,7 @@ class ProductFilter(django_filters.FilterSet):
|
|||
<p>If you're using <code>DjangoObjectPermissionsFilter</code>, you'll probably also want to add an appropriate object permissions class, to ensure that users can only operate on instances if they have the appropriate object permissions. The easiest way to do this is to subclass <code>DjangoObjectPermissions</code> and add <code>'view'</code> permissions to the <code>perms_map</code> attribute.</p>
|
||||
<p>A complete example using both <code>DjangoObjectPermissionsFilter</code> and <code>DjangoObjectPermissions</code> might look something like this.</p>
|
||||
<p><strong>permissions.py</strong>:</p>
|
||||
<pre class="prettyprint lang-py"><code>class CustomObjectPermissions(permissions.DjangoObjectPermissions):
|
||||
<pre><code>class CustomObjectPermissions(permissions.DjangoObjectPermissions):
|
||||
"""
|
||||
Similar to `DjangoObjectPermissions`, but adding 'view' permissions.
|
||||
"""
|
||||
|
|
@ -485,7 +715,7 @@ class ProductFilter(django_filters.FilterSet):
|
|||
}
|
||||
</code></pre>
|
||||
<p><strong>views.py</strong>:</p>
|
||||
<pre class="prettyprint lang-py"><code>class EventViewSet(viewsets.ModelViewSet):
|
||||
<pre><code>class EventViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Viewset that only lists events if user has 'view' permissions, and only
|
||||
allows operations on individual events if user has appropriate 'view', 'add',
|
||||
|
|
@ -504,7 +734,7 @@ class ProductFilter(django_filters.FilterSet):
|
|||
<p>As well as allowing clients to perform searches and filtering, generic filter backends can be useful for restricting which objects should be visible to any given request or user.</p>
|
||||
<h2 id="example">Example</h2>
|
||||
<p>For example, you might need to restrict users to only being able to see objects they created.</p>
|
||||
<pre class="prettyprint lang-py"><code>class IsOwnerFilterBackend(filters.BaseFilterBackend):
|
||||
<pre><code>class IsOwnerFilterBackend(filters.BaseFilterBackend):
|
||||
"""
|
||||
Filter that only allows users to see their own objects.
|
||||
"""
|
||||
|
|
@ -516,42 +746,52 @@ class ProductFilter(django_filters.FilterSet):
|
|||
<p>The following third party packages provide additional filter implementations.</p>
|
||||
<h2 id="django-rest-framework-chain">Django REST framework chain</h2>
|
||||
<p>The <a href="https://github.com/philipn/django-rest-framework-chain">django-rest-framework-chain package</a> works together with the <code>DjangoFilterBackend</code> class, and allows you to easily create filters across relationships, or create multiple filter lookup types for a given field.</p>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
</div>
|
||||
<!--/span-->
|
||||
</div>
|
||||
<!--/row-->
|
||||
</div>
|
||||
<!--/.fluid-container-->
|
||||
</div>
|
||||
<!--/.body content-->
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
<!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://www.django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="../../js/jquery-1.8.1-min.js"></script>
|
||||
<script src="../../js/prettify-1.0.js"></script>
|
||||
<script src="../../js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
</html>
|
||||
|
|
@ -1,291 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Format suffixes - Django REST framework</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/format-suffixes"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Format suffixes">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="format-suffixes-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/reverse">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/content-negotiation"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/third-party-resources">Third Party Resources</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/contributing">Contributing to REST framework</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.4-announcement">2.4 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/kickstarter-announcement">Kickstarter Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<!-- TODO
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Version: 2.0.0 <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Trunk</a></li>
|
||||
<li><a href="#">2.0.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span3">
|
||||
<!-- TODO
|
||||
<p style="margin-top: -12px">
|
||||
<a class="btn btn-mini btn-primary" style="width: 60px">« previous</a>
|
||||
<a class="btn btn-mini btn-primary" style="float: right; margin-right: 8px; width: 60px;">next »</a>
|
||||
</p>
|
||||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
<li class="main"><a href="#format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="#format_suffix_patterns">format_suffix_patterns</a></li>
|
||||
<li><a href="#accept-headers-vs-format-suffixes">Accept headers vs. format suffixes</a></li>
|
||||
|
||||
<div class="promo">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
<p><a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/urlpatterns.py"><span class="label label-info">urlpatterns.py</span></a></p>
|
||||
<h1 id="format-suffixes">Format suffixes</h1>
|
||||
<blockquote>
|
||||
<p>Section 6.2.1 does not say that content negotiation should be
|
||||
used all the time.</p>
|
||||
<p>— Roy Fielding, <a href="http://tech.groups.yahoo.com/group/rest-discuss/message/5857">REST discuss mailing list</a></p>
|
||||
</blockquote>
|
||||
<p>A common pattern for Web APIs is to use filename extensions on URLs to provide an endpoint for a given media type. For example, 'http://example.com/api/users.json' to serve a JSON representation. </p>
|
||||
<p>Adding format-suffix patterns to each individual entry in the URLconf for your API is error-prone and non-DRY, so REST framework provides a shortcut to adding these patterns to your URLConf.</p>
|
||||
<h2 id="format_suffix_patterns">format_suffix_patterns</h2>
|
||||
<p><strong>Signature</strong>: format_suffix_patterns(urlpatterns, suffix_required=False, allowed=None)</p>
|
||||
<p>Returns a URL pattern list which includes format suffix patterns appended to each of the URL patterns provided.</p>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li><strong>urlpatterns</strong>: Required. A URL pattern list.</li>
|
||||
<li><strong>suffix_required</strong>: Optional. A boolean indicating if suffixes in the URLs should be optional or mandatory. Defaults to <code>False</code>, meaning that suffixes are optional by default.</li>
|
||||
<li><strong>allowed</strong>: Optional. A list or tuple of valid format suffixes. If not provided, a wildcard format suffix pattern will be used. </li>
|
||||
</ul>
|
||||
<p>Example:</p>
|
||||
<pre class="prettyprint lang-py"><code>from rest_framework.urlpatterns import format_suffix_patterns
|
||||
from blog import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^/$', views.apt_root),
|
||||
url(r'^comments/$', views.comment_list),
|
||||
url(r'^comments/(?P<pk>[0-9]+)/$', views.comment_detail)
|
||||
]
|
||||
|
||||
urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html'])
|
||||
</code></pre>
|
||||
<p>When using <code>format_suffix_patterns</code>, you must make sure to add the <code>'format'</code> keyword argument to the corresponding views. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>@api_view(('GET', 'POST'))
|
||||
def comment_list(request, format=None):
|
||||
# do stuff...
|
||||
</code></pre>
|
||||
<p>Or with class based views:</p>
|
||||
<pre class="prettyprint lang-py"><code>class CommentList(APIView):
|
||||
def get(self, request, format=None):
|
||||
# do stuff...
|
||||
|
||||
def post(self, request, format=None):
|
||||
# do stuff...
|
||||
</code></pre>
|
||||
<p>The name of the kwarg used may be modified by using the <code>FORMAT_SUFFIX_KWARG</code> setting.</p>
|
||||
<p>Also note that <code>format_suffix_patterns</code> does not support descending into <code>include</code> URL patterns.</p>
|
||||
<hr />
|
||||
<h2 id="accept-headers-vs-format-suffixes">Accept headers vs. format suffixes</h2>
|
||||
<p>There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that <code>HTTP Accept</code> headers should always be used instead.</p>
|
||||
<p>It is actually a misconception. For example, take the following quote from Roy Fielding discussing the relative merits of query parameter media-type indicators vs. file extension media-type indicators: </p>
|
||||
<p>“That's why I always prefer extensions. Neither choice has anything to do with REST.” — Roy Fielding, <a href="http://tech.groups.yahoo.com/group/rest-discuss/message/14844">REST discuss mailing list</a></p>
|
||||
<p>The quote does not mention Accept headers, but it does make it clear that format suffixes should be considered an acceptable pattern.</p>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://www.django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
473
api-guide/format-suffixes/index.html
Normal file
473
api-guide/format-suffixes/index.html
Normal file
|
|
@ -0,0 +1,473 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Format suffixes - Django REST framework</title>
|
||||
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/format-suffixes/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Format suffixes">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="../../css/prettify.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="../../css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../reverse">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../content-negotiation">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li ><a href="/">Home</a></li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/quickstart">Quickstart</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/1-serialization">1 - Serialization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/2-requests-and-responses">2 - Requests and responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/3-class-based-views">3 - Class based views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/6-viewsets-and-routers">6- Viewsets and routers</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../requests">Requests</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../responses">Responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../views">Views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../generic-views">Generic views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../viewsets">Viewsets</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../routers">Routers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../parsers">Parsers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../renderers">Renderers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../serializers">Serializers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../fields">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../relations">Serializer relations</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../validators">Validators</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../authentication">Authentication</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../permissions">Permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../throttling">Throttling</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../filtering">Filtering</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../pagination">Pagination</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../content-negotiation">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href=".">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../reverse">Returning URLs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../exceptions">Exceptions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../status-codes">Status codes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../testing">Testing</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../settings">Settings</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li >
|
||||
<a href="../../topics/documenting-your-api">Documenting your API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/ajax-csrf-cors">AJAX, CSRF & CORS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browser-enhancements">Browser enhancements</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browsable-api">The Browsable API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/third-party-resources">Third Party Resources</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/contributing">Contributing to REST framework</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-framework-2-announcement">2.0 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.2-announcement">2.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.3-announcement">2.3 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.4-announcement">2.4 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/release-notes">Release Notes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/credits">Credits</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span3">
|
||||
<!-- TODO
|
||||
<p style="margin-top: -12px">
|
||||
<a class="btn btn-mini btn-primary" style="width: 60px">« previous</a>
|
||||
<a class="btn btn-mini btn-primary" style="float: right; margin-right: 8px; width: 60px;">next »</a>
|
||||
</p>
|
||||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#format-suffixes">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#format_suffix_patterns">format_suffix_patterns</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#accept-headers-vs-format-suffixes">Accept headers vs. format suffixes</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
|
||||
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/urlpatterns.py">
|
||||
<span class="label label-info">urlpatterns.py</span>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<h1 id="format-suffixes">Format suffixes</h1>
|
||||
<blockquote>
|
||||
<p>Section 6.2.1 does not say that content negotiation should be
|
||||
used all the time.</p>
|
||||
<p>— Roy Fielding, <a href="http://tech.groups.yahoo.com/group/rest-discuss/message/5857">REST discuss mailing list</a></p>
|
||||
</blockquote>
|
||||
<p>A common pattern for Web APIs is to use filename extensions on URLs to provide an endpoint for a given media type. For example, 'http://example.com/api/users.json' to serve a JSON representation.</p>
|
||||
<p>Adding format-suffix patterns to each individual entry in the URLconf for your API is error-prone and non-DRY, so REST framework provides a shortcut to adding these patterns to your URLConf.</p>
|
||||
<h2 id="format_suffix_patterns">format_suffix_patterns</h2>
|
||||
<p><strong>Signature</strong>: format_suffix_patterns(urlpatterns, suffix_required=False, allowed=None)</p>
|
||||
<p>Returns a URL pattern list which includes format suffix patterns appended to each of the URL patterns provided.</p>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li><strong>urlpatterns</strong>: Required. A URL pattern list.</li>
|
||||
<li><strong>suffix_required</strong>: Optional. A boolean indicating if suffixes in the URLs should be optional or mandatory. Defaults to <code>False</code>, meaning that suffixes are optional by default.</li>
|
||||
<li><strong>allowed</strong>: Optional. A list or tuple of valid format suffixes. If not provided, a wildcard format suffix pattern will be used.</li>
|
||||
</ul>
|
||||
<p>Example:</p>
|
||||
<pre><code>from rest_framework.urlpatterns import format_suffix_patterns
|
||||
from blog import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^/$', views.apt_root),
|
||||
url(r'^comments/$', views.comment_list),
|
||||
url(r'^comments/(?P<pk>[0-9]+)/$', views.comment_detail)
|
||||
]
|
||||
|
||||
urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html'])
|
||||
</code></pre>
|
||||
<p>When using <code>format_suffix_patterns</code>, you must make sure to add the <code>'format'</code> keyword argument to the corresponding views. For example:</p>
|
||||
<pre><code>@api_view(('GET', 'POST'))
|
||||
def comment_list(request, format=None):
|
||||
# do stuff...
|
||||
</code></pre>
|
||||
<p>Or with class based views:</p>
|
||||
<pre><code>class CommentList(APIView):
|
||||
def get(self, request, format=None):
|
||||
# do stuff...
|
||||
|
||||
def post(self, request, format=None):
|
||||
# do stuff...
|
||||
</code></pre>
|
||||
<p>The name of the kwarg used may be modified by using the <code>FORMAT_SUFFIX_KWARG</code> setting.</p>
|
||||
<p>Also note that <code>format_suffix_patterns</code> does not support descending into <code>include</code> URL patterns.</p>
|
||||
<hr />
|
||||
<h2 id="accept-headers-vs-format-suffixes">Accept headers vs. format suffixes</h2>
|
||||
<p>There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that <code>HTTP Accept</code> headers should always be used instead.</p>
|
||||
<p>It is actually a misconception. For example, take the following quote from Roy Fielding discussing the relative merits of query parameter media-type indicators vs. file extension media-type indicators:</p>
|
||||
<p>“That's why I always prefer extensions. Neither choice has anything to do with REST.” — Roy Fielding, <a href="http://tech.groups.yahoo.com/group/rest-discuss/message/14844">REST discuss mailing list</a></p>
|
||||
<p>The quote does not mention Accept headers, but it does make it clear that format suffixes should be considered an acceptable pattern.</p>
|
||||
|
||||
</div>
|
||||
<!--/span-->
|
||||
</div>
|
||||
<!--/row-->
|
||||
</div>
|
||||
<!--/.fluid-container-->
|
||||
</div>
|
||||
<!--/.body content-->
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
<!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="../../js/jquery-1.8.1-min.js"></script>
|
||||
<script src="../../js/prettify-1.0.js"></script>
|
||||
<script src="../../js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,65 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Generic views - Django REST framework</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/generic-views"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Generic views, API Reference, Mixins, Concrete View Classes, Customizing the generic views, Third party packages">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Generic views - Django REST framework</title>
|
||||
<link href="../../img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/generic-views/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Generic views">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<!-- Le styles -->
|
||||
<link href="../../css/prettify.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../../css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="../../css/default.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.type = 'text/javascript';
|
||||
ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="generic-views-page">
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/viewsets">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/views"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="prev" href="../viewsets">
|
||||
Next <i class="icon-arrow-right icon-white"></i>
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " rel="next" href="../views">
|
||||
<i class="icon-arrow-left icon-white"></i> Previous
|
||||
</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
|
|
@ -67,80 +76,218 @@ a.fusion-poweredby {
|
|||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li ><a href="/">Home</a></li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/quickstart">Quickstart</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/1-serialization">1 - Serialization</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/2-requests-and-responses">2 - Requests and responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/3-class-based-views">3 - Class based views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../tutorial/6-viewsets-and-routers">6- Viewsets and routers</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
|
||||
<li class="dropdown active">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../requests">Requests</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../responses">Responses</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../views">Views</a>
|
||||
</li>
|
||||
|
||||
<li class="active" >
|
||||
<a href=".">Generic views</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../viewsets">Viewsets</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../routers">Routers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../parsers">Parsers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../renderers">Renderers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../serializers">Serializers</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../fields">Serializer fields</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../relations">Serializer relations</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../validators">Validators</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../authentication">Authentication</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../permissions">Permissions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../throttling">Throttling</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../filtering">Filtering</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../pagination">Pagination</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../content-negotiation">Content negotiation</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../format-suffixes">Format suffixes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../reverse">Returning URLs</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../exceptions">Exceptions</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../status-codes">Status codes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../testing">Testing</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../settings">Settings</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/third-party-resources">Third Party Resources</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/contributing">Contributing to REST framework</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.4-announcement">2.4 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/kickstarter-announcement">Kickstarter Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/release-notes">Release Notes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/credits">Credits</a></li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/documenting-your-api">Documenting your API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/ajax-csrf-cors">AJAX, CSRF & CORS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browser-enhancements">Browser enhancements</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/browsable-api">The Browsable API</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/third-party-resources">Third Party Resources</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/contributing">Contributing to REST framework</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/rest-framework-2-announcement">2.0 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.2-announcement">2.2 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.3-announcement">2.3 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/2.4-announcement">2.4 Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/kickstarter-announcement">Kickstarter Announcement</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/release-notes">Release Notes</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="../../topics/credits">Credits</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<!-- TODO
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Version: 2.0.0 <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Trunk</a></li>
|
||||
<li><a href="#">2.0.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -148,32 +295,34 @@ a.fusion-poweredby {
|
|||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
|
|
@ -186,44 +335,164 @@ a.fusion-poweredby {
|
|||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
<li class="main"><a href="#generic-views">Generic views</a></li>
|
||||
<li><a href="#examples">Examples</a></li>
|
||||
<li class="main"><a href="#api-reference">API Reference</a></li>
|
||||
<li><a href="#genericapiview">GenericAPIView</a></li>
|
||||
<li class="main"><a href="#mixins">Mixins</a></li>
|
||||
<li><a href="#listmodelmixin">ListModelMixin</a></li>
|
||||
<li><a href="#createmodelmixin">CreateModelMixin</a></li>
|
||||
<li><a href="#retrievemodelmixin">RetrieveModelMixin</a></li>
|
||||
<li><a href="#updatemodelmixin">UpdateModelMixin</a></li>
|
||||
<li><a href="#destroymodelmixin">DestroyModelMixin</a></li>
|
||||
<li class="main"><a href="#concrete-view-classes">Concrete View Classes</a></li>
|
||||
<li><a href="#createapiview">CreateAPIView</a></li>
|
||||
<li><a href="#listapiview">ListAPIView</a></li>
|
||||
<li><a href="#retrieveapiview">RetrieveAPIView</a></li>
|
||||
<li><a href="#destroyapiview">DestroyAPIView</a></li>
|
||||
<li><a href="#updateapiview">UpdateAPIView</a></li>
|
||||
<li><a href="#listcreateapiview">ListCreateAPIView</a></li>
|
||||
<li><a href="#retrieveupdateapiview">RetrieveUpdateAPIView</a></li>
|
||||
<li><a href="#retrievedestroyapiview">RetrieveDestroyAPIView</a></li>
|
||||
<li><a href="#retrieveupdatedestroyapiview">RetrieveUpdateDestroyAPIView</a></li>
|
||||
<li class="main"><a href="#customizing-the-generic-views">Customizing the generic views</a></li>
|
||||
<li><a href="#creating-custom-mixins">Creating custom mixins</a></li>
|
||||
<li><a href="#creating-custom-base-classes">Creating custom base classes</a></li>
|
||||
<li class="main"><a href="#third-party-packages">Third party packages</a></li>
|
||||
<li><a href="#django-rest-framework-bulk">Django REST Framework bulk</a></li>
|
||||
|
||||
<div class="promo">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#generic-views">Generic views</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#examples">Examples</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#api-reference">API Reference</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#genericapiview">GenericAPIView</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#mixins">Mixins</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#listmodelmixin">ListModelMixin</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#createmodelmixin">CreateModelMixin</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#retrievemodelmixin">RetrieveModelMixin</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#updatemodelmixin">UpdateModelMixin</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#destroymodelmixin">DestroyModelMixin</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#concrete-view-classes">Concrete View Classes</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#createapiview">CreateAPIView</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#listapiview">ListAPIView</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#retrieveapiview">RetrieveAPIView</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#destroyapiview">DestroyAPIView</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#updateapiview">UpdateAPIView</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#listcreateapiview">ListCreateAPIView</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#retrieveupdateapiview">RetrieveUpdateAPIView</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#retrievedestroyapiview">RetrieveDestroyAPIView</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#retrieveupdatedestroyapiview">RetrieveUpdateDestroyAPIView</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#customizing-the-generic-views">Customizing the generic views</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#creating-custom-mixins">Creating custom mixins</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#creating-custom-base-classes">Creating custom base classes</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#put-as-create">PUT as create</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="main">
|
||||
<a href="#third-party-packages">Third party packages</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#django-rest-framework-bulk">Django REST Framework bulk</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
<p><a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/mixins.py"><span class="label label-info">mixins.py</span></a>
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/generics.py"><span class="label label-info">generics.py</span></a></p>
|
||||
<h1 id="generic-views">Generic views</h1>
|
||||
|
||||
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/mixins.py">
|
||||
<span class="label label-info">mixins.py</span>
|
||||
</a>
|
||||
|
||||
<a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/generics.py">
|
||||
<span class="label label-info">generics.py</span>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
<h1 id="generic-views">Generic views</h1>
|
||||
<blockquote>
|
||||
<p>Django’s generic views... were developed as a shortcut for common usage patterns... They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to repeat yourself.</p>
|
||||
<p>— <a href="https://docs.djangoproject.com/en/dev/ref/class-based-views/#base-vs-generic-views">Django Documentation</a></p>
|
||||
|
|
@ -233,7 +502,7 @@ a.fusion-poweredby {
|
|||
<p>If the generic views don't suit the needs of your API, you can drop down to using the regular <code>APIView</code> class, or reuse the mixins and base classes used by the generic views to compose your own set of reusable generic views.</p>
|
||||
<h2 id="examples">Examples</h2>
|
||||
<p>Typically when using the generic views, you'll override the view, and set several class attributes.</p>
|
||||
<pre class="prettyprint lang-py"><code>from django.contrib.auth.models import User
|
||||
<pre><code>from django.contrib.auth.models import User
|
||||
from myapp.serializers import UserSerializer
|
||||
from rest_framework import generics
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
|
|
@ -245,7 +514,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
paginate_by = 100
|
||||
</code></pre>
|
||||
<p>For more complex cases you might also want to override various methods on the view class. For example.</p>
|
||||
<pre class="prettyprint lang-py"><code>class UserList(generics.ListCreateAPIView):
|
||||
<pre><code>class UserList(generics.ListCreateAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserSerializer
|
||||
permission_classes = (IsAdminUser,)
|
||||
|
|
@ -265,7 +534,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
return Response(serializer.data)
|
||||
</code></pre>
|
||||
<p>For very simple cases you might want to pass through any class attributes using the <code>.as_view()</code> method. For example, your URLconf might include something like the following entry:</p>
|
||||
<pre class="prettyprint lang-py"><code>url(r'^/users/', ListCreateAPIView.as_view(model=User), name='user-list')
|
||||
<pre><code>url(r'^/users/', ListCreateAPIView.as_view(model=User), name='user-list')
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h1 id="api-reference">API Reference</h1>
|
||||
|
|
@ -304,7 +573,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
<p>This method should always be used rather than accessing <code>self.queryset</code> directly, as <code>self.queryset</code> gets evaluated only once, and those results are cached for all subsequent requests.</p>
|
||||
<p>May be overridden to provide dynamic behavior, such as returning a queryset, that is specific to the user making the request.</p>
|
||||
<p>For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>def get_queryset(self):
|
||||
<pre><code>def get_queryset(self):
|
||||
user = self.request.user
|
||||
return user.accounts.all()
|
||||
</code></pre>
|
||||
|
|
@ -312,7 +581,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
<p>Returns an object instance that should be used for detail views. Defaults to using the <code>lookup_field</code> parameter to filter the base queryset.</p>
|
||||
<p>May be overridden to provide more complex behavior, such as object lookups based on more than one URL kwarg.</p>
|
||||
<p>For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>def get_object(self):
|
||||
<pre><code>def get_object(self):
|
||||
queryset = self.get_queryset()
|
||||
filter = {}
|
||||
for field in self.multiple_lookup_fields:
|
||||
|
|
@ -327,7 +596,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
<p>Returns the classes that should be used to filter the queryset. Defaults to returning the <code>filter_backends</code> attribute.</p>
|
||||
<p>May be overridden to provide more complex behavior with filters, such as using different (or even exlusive) lists of filter_backends depending on different criteria.</p>
|
||||
<p>For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>def get_filter_backends(self):
|
||||
<pre><code>def get_filter_backends(self):
|
||||
if "geo_route" in self.request.QUERY_PARAMS:
|
||||
return (GeoRouteFilter, CategoryFilter)
|
||||
elif "geo_point" in self.request.QUERY_PARAMS:
|
||||
|
|
@ -339,7 +608,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
<p>Returns the class that should be used for the serializer. Defaults to returning the <code>serializer_class</code> attribute, or dynamically generating a serializer class if the <code>model</code> shortcut is being used.</p>
|
||||
<p>May be overridden to provide dynamic behavior, such as using different serializers for read and write operations, or providing different serializers to different types of users.</p>
|
||||
<p>For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>def get_serializer_class(self):
|
||||
<pre><code>def get_serializer_class(self):
|
||||
if self.request.user.is_staff:
|
||||
return FullAccountSerializer
|
||||
return BasicAccountSerializer
|
||||
|
|
@ -348,7 +617,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
<p>Returns the page size to use with pagination. By default this uses the <code>paginate_by</code> attribute, and may be overridden by the client if the <code>paginate_by_param</code> attribute is set.</p>
|
||||
<p>You may want to override this method to provide more complex behavior, such as modifying page sizes based on the media type of the response.</p>
|
||||
<p>For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>def get_paginate_by(self):
|
||||
<pre><code>def get_paginate_by(self):
|
||||
if self.request.accepted_renderer.format == 'html':
|
||||
return 20
|
||||
return 100
|
||||
|
|
@ -362,7 +631,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
<li><code>post_delete(self, obj)</code> - A hook that is called after deleting an object.</li>
|
||||
</ul>
|
||||
<p>The <code>pre_save</code> method in particular is a useful hook for setting attributes that are implicit in the request, but are not part of the request data. For instance, you might set an attribute on the object based on the request user, or based on a URL keyword argument.</p>
|
||||
<pre class="prettyprint lang-py"><code>def pre_save(self, obj):
|
||||
<pre><code>def pre_save(self, obj):
|
||||
"""
|
||||
Set the object's owner, based on the incoming request.
|
||||
"""
|
||||
|
|
@ -384,7 +653,6 @@ class UserList(generics.ListCreateAPIView):
|
|||
<h2 id="listmodelmixin">ListModelMixin</h2>
|
||||
<p>Provides a <code>.list(request, *args, **kwargs)</code> method, that implements listing a queryset.</p>
|
||||
<p>If the queryset is populated, this returns a <code>200 OK</code> response, with a serialized representation of the queryset as the body of the response. The response data may optionally be paginated.</p>
|
||||
<p>If the queryset is empty this returns a <code>200 OK</code> response, unless the <code>.allow_empty</code> attribute on the view is set to <code>False</code>, in which case it will return a <code>404 Not Found</code>.</p>
|
||||
<h2 id="createmodelmixin">CreateModelMixin</h2>
|
||||
<p>Provides a <code>.create(request, *args, **kwargs)</code> method, that implements creating and saving a new model instance.</p>
|
||||
<p>If an object is created this returns a <code>201 Created</code> response, with a serialized representation of the object as the body of the response. If the representation contains a key named <code>url</code>, then the <code>Location</code> header of the response will be populated with that value.</p>
|
||||
|
|
@ -445,7 +713,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
<p>Often you'll want to use the existing generic views, but use some slightly customized behavior. If you find yourself reusing some bit of customized behavior in multiple places, you might want to refactor the behavior into a common class that you can then just apply to any view or viewset as needed.</p>
|
||||
<h2 id="creating-custom-mixins">Creating custom mixins</h2>
|
||||
<p>For example, if you need to lookup objects based on multiple fields in the URL conf, you could create a mixin class like the following:</p>
|
||||
<pre class="prettyprint lang-py"><code>class MultipleFieldLookupMixin(object):
|
||||
<pre><code>class MultipleFieldLookupMixin(object):
|
||||
"""
|
||||
Apply this mixin to any view or viewset to get multiple field filtering
|
||||
based on a `lookup_fields` attribute, instead of the default single field filtering.
|
||||
|
|
@ -459,7 +727,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
return get_object_or_404(queryset, **filter) # Lookup the object
|
||||
</code></pre>
|
||||
<p>You can then simply apply this mixin to a view or viewset anytime you need to apply the custom behavior.</p>
|
||||
<pre class="prettyprint lang-py"><code>class RetrieveUserView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
|
||||
<pre><code>class RetrieveUserView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserSerializer
|
||||
lookup_fields = ('account', 'username')
|
||||
|
|
@ -467,7 +735,7 @@ class UserList(generics.ListCreateAPIView):
|
|||
<p>Using custom mixins is a good option if you have custom behavior that needs to be used</p>
|
||||
<h2 id="creating-custom-base-classes">Creating custom base classes</h2>
|
||||
<p>If you are using a mixin across multiple views, you can take this a step further and create your own set of base views that can then be used throughout your project. For example:</p>
|
||||
<pre class="prettyprint lang-py"><code>class BaseRetrieveView(MultipleFieldLookupMixin,
|
||||
<pre><code>class BaseRetrieveView(MultipleFieldLookupMixin,
|
||||
generics.RetrieveAPIView):
|
||||
pass
|
||||
|
||||
|
|
@ -476,46 +744,63 @@ class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,
|
|||
pass
|
||||
</code></pre>
|
||||
<p>Using custom base classes is a good option if you have custom behavior that consistently needs to be repeated across a large number of views throughout your project.</p>
|
||||
<hr />
|
||||
<h1 id="put-as-create">PUT as create</h1>
|
||||
<p>Prior to version 3.0 the REST framework mixins treated <code>PUT</code> as either an update or a create operation, depending on if the object already existed or not.</p>
|
||||
<p>Allowing <code>PUT</code> as create operations is problematic, as it necessarily exposes information about the existence or non-existence of objects. It's also not obvious that transparently allowing re-creating of previously deleted instances is necessarily a better default behavior than simply returning <code>404</code> responses.</p>
|
||||
<p>Both styles "<code>PUT</code> as 404" and "<code>PUT</code> as create" can be valid in different circumstances, but from version 3.0 onwards we now use 404 behavior as the default, due to it being simpler and more obvious.</p>
|
||||
<p>If you need to generic PUT-as-create behavior you may want to include something like <a href="https://gist.github.com/tomchristie/a2ace4577eff2c603b1b">this <code>AllowPUTAsCreateMixin</code> class</a> as a mixin to your views.</p>
|
||||
<hr />
|
||||
<h1 id="third-party-packages">Third party packages</h1>
|
||||
<p>The following third party packages provide additional generic view implementations.</p>
|
||||
<h2 id="django-rest-framework-bulk">Django REST Framework bulk</h2>
|
||||
<p>The <a href="https://github.com/miki725/django-rest-framework-bulk">django-rest-framework-bulk package</a> implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests.</p>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
</div>
|
||||
<!--/span-->
|
||||
</div>
|
||||
<!--/row-->
|
||||
</div>
|
||||
<!--/.fluid-container-->
|
||||
</div>
|
||||
<!--/.body content-->
|
||||
<div id="push"></div>
|
||||
</div>
|
||||
<!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://www.django-rest-framework.org/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/prettify-1.0.js"></script>
|
||||
<script src="http://www.django-rest-framework.org/js/bootstrap-2.1.1-min.js"></script>
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="../../js/jquery-1.8.1-min.js"></script>
|
||||
<script src="../../js/prettify-1.0.js"></script>
|
||||
<script src="../../js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() {
|
||||
scrollBy(0, -50)
|
||||
};
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function() {
|
||||
$(window).resize(function() {
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
</html>
|
||||
|
|
@ -1,324 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Metadata - Django REST framework</title>
|
||||
<link href="file:///Users/tomchristie/GitHub/django-rest-framework/html//img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/metadata.html"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Metadata, Custom metadata classes">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="file:///Users/tomchristie/GitHub/django-rest-framework/html//css/prettify.css" rel="stylesheet">
|
||||
<link href="file:///Users/tomchristie/GitHub/django-rest-framework/html//css/bootstrap.css" rel="stylesheet">
|
||||
<link href="file:///Users/tomchristie/GitHub/django-rest-framework/html//css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="file:///Users/tomchristie/GitHub/django-rest-framework/html//css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="metadata-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small disabled" href="#">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small disabled" href="#"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="file:///Users/tomchristie/GitHub/django-rest-framework/html/index.html">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html/index.html">Home</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//tutorial/quickstart.html">Quickstart</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//tutorial/1-serialization.html">1 - Serialization</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//tutorial/2-requests-and-responses.html">2 - Requests and responses</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//tutorial/3-class-based-views.html">3 - Class based views</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//tutorial/4-authentication-and-permissions.html">4 - Authentication and permissions</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//tutorial/5-relationships-and-hyperlinked-apis.html">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//tutorial/6-viewsets-and-routers.html">6 - Viewsets and routers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/requests.html">Requests</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/responses.html">Responses</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/views.html">Views</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/generic-views.html">Generic views</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/viewsets.html">Viewsets</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/routers.html">Routers</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/parsers.html">Parsers</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/renderers.html">Renderers</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/serializers.html">Serializers</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/fields.html">Serializer fields</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/relations.html">Serializer relations</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/validators.html">Validators</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/authentication.html">Authentication</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/permissions.html">Permissions</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/throttling.html">Throttling</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/filtering.html">Filtering</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/pagination.html">Pagination</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/content-negotiation.html">Content negotiation</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/format-suffixes.html">Format suffixes</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/reverse.html">Returning URLs</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/exceptions.html">Exceptions</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/status-codes.html">Status codes</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/testing.html">Testing</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//api-guide/settings.html">Settings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/documenting-your-api.html">Documenting your API</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/ajax-csrf-cors.html">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/browser-enhancements.html">Browser enhancements</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/browsable-api.html">The Browsable API</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/rest-hypermedia-hateoas.html">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/third-party-resources.html">Third Party Resources</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/contributing.html">Contributing to REST framework</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/rest-framework-2-announcement.html">2.0 Announcement</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/2.2-announcement.html">2.2 Announcement</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/2.3-announcement.html">2.3 Announcement</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/2.4-announcement.html">2.4 Announcement</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/kickstarter-announcement.html">Kickstarter Announcement</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/release-notes.html">Release Notes</a></li>
|
||||
<li><a href="file:///Users/tomchristie/GitHub/django-rest-framework/html//topics/credits.html">Credits</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<!-- TODO
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Version: 2.0.0 <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Trunk</a></li>
|
||||
<li><a href="#">2.0.0</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body-content">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Search Modal -->
|
||||
<div id="searchModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="myModalLabel">Documentation search</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Custom google search -->
|
||||
<script>
|
||||
(function() {
|
||||
var cx = '015016005043623903336:rxraeohqk6w';
|
||||
var gcse = document.createElement('script');
|
||||
gcse.type = 'text/javascript';
|
||||
gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
|
||||
'//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
</script>
|
||||
<gcse:search></gcse:search>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span3">
|
||||
<!-- TODO
|
||||
<p style="margin-top: -12px">
|
||||
<a class="btn btn-mini btn-primary" style="width: 60px">« previous</a>
|
||||
<a class="btn btn-mini btn-primary" style="float: right; margin-right: 8px; width: 60px;">next »</a>
|
||||
</p>
|
||||
-->
|
||||
<div id="table-of-contents">
|
||||
<ul class="nav nav-list side-nav well sidebar-nav-fixed">
|
||||
<li class="main"><a href="#metadata">Metadata</a></li>
|
||||
<li><a href="#setting-the-metadata-scheme">Setting the metadata scheme</a></li>
|
||||
<li><a href="#creating-schema-endpoints">Creating schema endpoints</a></li>
|
||||
<li class="main"><a href="#custom-metadata-classes">Custom metadata classes</a></li>
|
||||
<li><a href="#example">Example</a></li>
|
||||
|
||||
<div class="promo">
|
||||
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="main-content" class="span9">
|
||||
<p><a class="github" href="https://github.com/tomchristie/django-rest-framework/tree/master/rest_framework/metadata.py"><span class="label label-info">metadata.py</span></a></p>
|
||||
<h1 id="metadata">Metadata</h1>
|
||||
<blockquote>
|
||||
<p>[The <code>OPTIONS</code>] method allows a client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.</p>
|
||||
<p>— <a href="http://tools.ietf.org/html/rfc7231#section-4.3.7">RFC7231, Section 4.3.7.</a></p>
|
||||
</blockquote>
|
||||
<p>REST framework includes a configurable mechanism for determining how your API should respond to <code>OPTIONS</code> requests. This allows you to return API schema or other resource information.</p>
|
||||
<p>There are not currently any widely adopted conventions for exactly what style of response should be returned for HTTP <code>OPTIONS</code> requests, so we provide an ad-hoc style that returns some useful information.</p>
|
||||
<p>Here's an example response that demonstrates the information that is returned by default.</p>
|
||||
<pre class="prettyprint lang-py"><code>HTTP 200 OK
|
||||
Allow: GET, POST, HEAD, OPTIONS
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "To Do List",
|
||||
"description": "List existing 'To Do' items, or create a new item.",
|
||||
"renders": [
|
||||
"application/json",
|
||||
"text/html"
|
||||
],
|
||||
"parses": [
|
||||
"application/json",
|
||||
"application/x-www-form-urlencoded",
|
||||
"multipart/form-data"
|
||||
],
|
||||
"actions": {
|
||||
"POST": {
|
||||
"note": {
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"read_only": false,
|
||||
"label": "title",
|
||||
"max_length": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<h2 id="setting-the-metadata-scheme">Setting the metadata scheme</h2>
|
||||
<p>You can set the metadata class globally using the <code>'DEFAULT_METADATA_CLASS'</code> settings key:</p>
|
||||
<pre class="prettyprint lang-py"><code>REST_FRAMEWORK = {
|
||||
'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata'
|
||||
}
|
||||
</code></pre>
|
||||
<p>Or you can set the metadata class individually for a view:</p>
|
||||
<pre class="prettyprint lang-py"><code>class APIRoot(APIView):
|
||||
metadata_class = APIRootMetadata
|
||||
|
||||
def get(self, request, format=None):
|
||||
return Response({
|
||||
...
|
||||
})
|
||||
</code></pre>
|
||||
<p>The REST framework package only includes a single metadata class implementation, named <code>SimpleMetadata</code>. If you want to use an alternative style you'll need to implement a custom metadata class.</p>
|
||||
<h2 id="creating-schema-endpoints">Creating schema endpoints</h2>
|
||||
<p>If you have specific requirements for creating schema endpoints that are accessed with regular <code>GET</code> requests, you might consider re-using the metadata API for doing so.</p>
|
||||
<p>For example, the following additional route could be used on a viewset to provide a linkable schema endpoint.</p>
|
||||
<pre class="prettyprint lang-py"><code>@list_route(methods=['GET'])
|
||||
def schema(self, request):
|
||||
meta = self.metadata_class()
|
||||
data = meta.determine_metadata(request, self)
|
||||
return Response(data)
|
||||
</code></pre>
|
||||
<p>There are a couple of reasons that you might choose to take this approach, including that <code>OPTIONS</code> responses <a href="https://www.mnot.net/blog/2012/10/29/NO_OPTIONS">are not cacheable</a>.</p>
|
||||
<hr />
|
||||
<h1 id="custom-metadata-classes">Custom metadata classes</h1>
|
||||
<p>If you want to provide a custom metadata class you should override <code>BaseMetadata</code> and implement the <code>determine_metadata(self, request, view)</code> method.</p>
|
||||
<p>Useful things that you might want to do could include returning schema information, using a format such as <a href="http://json-schema.org/">JSON schema</a>, or returning debug information to admin users.</p>
|
||||
<h2 id="example">Example</h2>
|
||||
<p>The following class could be used to limit the information that is returned to <code>OPTIONS</code> requests.</p>
|
||||
<pre class="prettyprint lang-py"><code>class MinimalMetadata(BaseMetadata):
|
||||
"""
|
||||
Don't include field and other information for `OPTIONS` requests.
|
||||
Just return the name and description.
|
||||
"""
|
||||
def determine_metadata(self, request, view):
|
||||
return {
|
||||
'name': view.get_view_name(),
|
||||
'description': view.get_view_description()
|
||||
}
|
||||
</code></pre>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
</div><!--/.fluid-container-->
|
||||
</div><!--/.body content-->
|
||||
|
||||
<div id="push"></div>
|
||||
</div><!--/.wrapper -->
|
||||
|
||||
<footer class="span12">
|
||||
<p>Sponsored by <a href="http://dabapps.com/">DabApps</a>.</a></p>
|
||||
</footer>
|
||||
|
||||
<!-- Le javascript
|
||||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="file:///Users/tomchristie/GitHub/django-rest-framework/html//js/jquery-1.8.1-min.js"></script>
|
||||
<script src="file:///Users/tomchristie/GitHub/django-rest-framework/html//js/prettify-1.0.js"></script>
|
||||
<script src="file:///Users/tomchristie/GitHub/django-rest-framework/html//js/bootstrap-2.1.1-min.js"></script>
|
||||
|
||||
<script>
|
||||
//$('.side-nav').scrollspy()
|
||||
var shiftWindow = function() { scrollBy(0, -50) };
|
||||
if (location.hash) shiftWindow();
|
||||
window.addEventListener("hashchange", shiftWindow);
|
||||
|
||||
$('.dropdown-menu').on('click touchstart', function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// Dynamically force sidenav to no higher than browser window
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
|
||||
$(function(){
|
||||
$(window).resize(function(){
|
||||
$('.side-nav').css('max-height', window.innerHeight - 130);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
|
|
@ -1,373 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Pagination - Django REST framework</title>
|
||||
<link href="http://www.django-rest-framework.org/img/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link rel="canonical" href="http://www.django-rest-framework.org/api-guide/pagination"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Django, API, REST, Pagination, Custom pagination serializers, Third party packages">
|
||||
<meta name="author" content="Tom Christie">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://www.django-rest-framework.org/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://www.django-rest-framework.org/css/default.css" rel="stylesheet">
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-18852272-2']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
|
||||
</script>
|
||||
<style>
|
||||
span.fusion-wrap a {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.fusion-poweredby {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
div.promo {display: none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="prettyPrint()" class="pagination-page">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<a class="repo-link btn btn-primary btn-small" href="https://github.com/tomchristie/django-rest-framework/tree/master">GitHub</a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/content-negotiation">Next <i class="icon-arrow-right icon-white"></i></a>
|
||||
<a class="repo-link btn btn-inverse btn-small " href="../api-guide/filtering"><i class="icon-arrow-left icon-white"></i> Previous</a>
|
||||
<a class="repo-link btn btn-inverse btn-small" href="#searchModal" data-toggle="modal"><i class="icon-search icon-white"></i> Search</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="http://www.django-rest-framework.org">Django REST framework</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a href="http://www.django-rest-framework.org">Home</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/quickstart">Quickstart</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/1-serialization">1 - Serialization</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/2-requests-and-responses">2 - Requests and responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/3-class-based-views">3 - Class based views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions">4 - Authentication and permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis">5 - Relationships and hyperlinked APIs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers">6 - Viewsets and routers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Guide <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/requests">Requests</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/responses">Responses</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/views">Views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/generic-views">Generic views</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/viewsets">Viewsets</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/routers">Routers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/parsers">Parsers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/renderers">Renderers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/serializers">Serializers</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/fields">Serializer fields</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/relations">Serializer relations</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/authentication">Authentication</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/permissions">Permissions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/throttling">Throttling</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/filtering">Filtering</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/pagination">Pagination</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/content-negotiation">Content negotiation</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/format-suffixes">Format suffixes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/reverse">Returning URLs</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/exceptions">Exceptions</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/status-codes">Status codes</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/testing">Testing</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/api-guide/settings">Settings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Topics <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="http://www.django-rest-framework.org/topics/documenting-your-api">Documenting your API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/ajax-csrf-cors">AJAX, CSRF & CORS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browser-enhancements">Browser enhancements</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/browsable-api">The Browsable API</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas">REST, Hypermedia & HATEOAS</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/third-party-resources">Third Party Resources</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/contributing">Contributing to REST framework</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/rest-framework-2-announcement">2.0 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.2-announcement">2.2 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.3-announcement">2.3 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/2.4-announcement">2.4 Announcement</a></li>
|
||||
<li><a href="http://www.django-rest-framework.org/topics/kickstarter-announcement">Kickstarter Announcement</a></li>
|
||||