mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-12-04 07:24:03 +03:00
Code highlighting
This commit is contained in:
parent
ea9f8a16e2
commit
1fab487030
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -113,7 +114,7 @@
|
|||
<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-policy">Setting the authentication policy</h2>
|
||||
<p>The default authentication policy may be set globally, using the <code>DEFAULT_AUTHENTICATION</code> setting. For example.</p>
|
||||
<pre><code>API_SETTINGS = {
|
||||
<pre class="prettyprint lang-py"><code>API_SETTINGS = {
|
||||
'DEFAULT_AUTHENTICATION': (
|
||||
'djangorestframework.authentication.UserBasicAuthentication',
|
||||
'djangorestframework.authentication.SessionAuthentication',
|
||||
|
@ -121,7 +122,7 @@
|
|||
}
|
||||
</code></pre>
|
||||
<p>You can also set the authentication policy on a per-view basis, using the <code>APIView</code> class based views.</p>
|
||||
<pre><code>class ExampleView(APIView):
|
||||
<pre class="prettyprint lang-py"><code>class ExampleView(APIView):
|
||||
authentication_classes = (SessionAuthentication, UserBasicAuthentication)
|
||||
|
||||
def get(self, request, format=None):
|
||||
|
@ -132,7 +133,7 @@
|
|||
return Response(content)
|
||||
</code></pre>
|
||||
<p>Or, if you're using the <code>@api_view</code> decorator with function based views.</p>
|
||||
<pre><code>@api_view(
|
||||
<pre class="prettyprint lang-py"><code>@api_view(
|
||||
allowed=('GET',),
|
||||
authentication_classes=(SessionAuthentication, UserBasicAuthentication)
|
||||
)
|
||||
|
@ -153,7 +154,7 @@ def example_view(request, format=None):
|
|||
</ul>
|
||||
<h2 id="tokenauthentication">TokenAuthentication</h2>
|
||||
<p>This policy uses <a href="http://tools.ietf.org/html/rfc2617">HTTP Authentication</a> with no authentication scheme. Token basic authentication is appropriate for client-server setups, such as native desktop and mobile clients. The token key should be passed in as a string to the "Authorization" HTTP header. For example:</p>
|
||||
<pre><code>curl http://my.api.org/ -X POST -H "Authorization: 0123456789abcdef0123456789abcdef"
|
||||
<pre class="prettyprint lang-py"><code>curl http://my.api.org/ -X POST -H "Authorization: 0123456789abcdef0123456789abcdef"
|
||||
</code></pre>
|
||||
<p><strong>Note:</strong> If you run <code>TokenAuthentication</code> in production your API must be <code>https</code> only, or it will be completely insecure.</p>
|
||||
<p>If successfully authenticated, <code>TokenAuthentication</code> provides the following credentials.</p>
|
||||
|
@ -186,6 +187,7 @@ def example_view(request, format=None):
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -104,6 +105,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -103,6 +104,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -105,6 +106,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -102,6 +103,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -105,6 +106,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -146,6 +147,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -118,6 +119,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -113,7 +114,7 @@
|
|||
<p>There's no requirement for you to use them, but if you do then the self-describing API will be able to automatically hyperlink it's output for you, which makes browsing the API much easier.</p>
|
||||
<h2 id="reverseviewname-request-args-kwargs">reverse(viewname, request, <em>args, </em>*kwargs)</h2>
|
||||
<p>Has the same behavior as <a href="https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse"><code>django.core.urlresolvers.reverse</code></a>, except that it returns a fully qualified URL, using the request to determine the host and port.</p>
|
||||
<pre><code>from djangorestframework.utils import reverse
|
||||
<pre class="prettyprint lang-py"><code>from djangorestframework.utils import reverse
|
||||
from djangorestframework.views import APIView
|
||||
|
||||
class MyView(APIView):
|
||||
|
@ -134,6 +135,7 @@ class MyView(APIView):
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -118,7 +119,7 @@ area would be gratefully accepted.</p>
|
|||
<p>REST framework's serializers work very similarly to Django's <code>Form</code> and <code>ModelForm</code> classes. It provides a <code>Serializer</code> class which gives you a powerful, generic way to control the output of your responses, as well as a <code>ModelSerializer</code> class which provides a useful shortcut for creating serializers that deal with model instances and querysets.</p>
|
||||
<h2 id="declaring-serializers">Declaring Serializers</h2>
|
||||
<p>Let's start by creating a simple object we can use for example purposes:</p>
|
||||
<pre><code>class Comment(object):
|
||||
<pre class="prettyprint lang-py"><code>class Comment(object):
|
||||
def __init__(self, email, content, created=None):
|
||||
self.email = email
|
||||
self.content = content
|
||||
|
@ -128,7 +129,7 @@ comment = Comment(email='leila@example.com', content='foo bar')
|
|||
</code></pre>
|
||||
<p>We'll declare a serializer that we can use to serialize and deserialize <code>Comment</code> objects.
|
||||
Declaring a serializer looks very similar to declaring a form:</p>
|
||||
<pre><code>class CommentSerializer(serializers.Serializer):
|
||||
<pre class="prettyprint lang-py"><code>class CommentSerializer(serializers.Serializer):
|
||||
email = serializers.EmailField()
|
||||
content = serializers.CharField(max_length=200)
|
||||
created = serializers.DateTimeField()
|
||||
|
@ -144,21 +145,21 @@ Declaring a serializer looks very similar to declaring a form:</p>
|
|||
<p>The first part of serializer class defines the fields that get serialized/deserialized. The <code>restore_object</code> method defines how fully fledged instances get created when deserializing data. The <code>restore_object</code> method is optional, and is only required if we want our serializer to support deserialization.</p>
|
||||
<h2 id="serializing-objects">Serializing objects</h2>
|
||||
<p>We can now use <code>CommentSerializer</code> to serialize a comment, or list of comments. Again, using the <code>Serializer</code> class looks a lot like using a <code>Form</code> class.</p>
|
||||
<pre><code>serializer = CommentSerializer(instance=comment)
|
||||
<pre class="prettyprint lang-py"><code>serializer = CommentSerializer(instance=comment)
|
||||
serializer.data
|
||||
# {'email': u'leila@example.com', 'content': u'foo bar', 'created': datetime.datetime(2012, 8, 22, 16, 20, 9, 822774)}
|
||||
</code></pre>
|
||||
<p>At this point we've translated the model instance into python native datatypes. To finalise the serialization process we render the data into <code>json</code>.</p>
|
||||
<pre><code>stream = JSONRenderer().render(data)
|
||||
<pre class="prettyprint lang-py"><code>stream = JSONRenderer().render(data)
|
||||
stream
|
||||
# '{"email": "leila@example.com", "content": "foo bar", "created": "2012-08-22T16:20:09.822"}'
|
||||
</code></pre>
|
||||
<h2 id="deserializing-objects">Deserializing objects</h2>
|
||||
<p>Deserialization is similar. First we parse a stream into python native datatypes... </p>
|
||||
<pre><code>data = JSONParser().parse(stream)
|
||||
<pre class="prettyprint lang-py"><code>data = JSONParser().parse(stream)
|
||||
</code></pre>
|
||||
<p>...then we restore those native datatypes into a fully populated object instance.</p>
|
||||
<pre><code>serializer = CommentSerializer(data)
|
||||
<pre class="prettyprint lang-py"><code>serializer = CommentSerializer(data)
|
||||
serializer.is_valid()
|
||||
# True
|
||||
serializer.object
|
||||
|
@ -172,7 +173,7 @@ serializer.object
|
|||
<p>The previous example is fine for dealing with objects that only have simple datatypes, but sometimes we also need to be able to represent more complex objects,
|
||||
where some of the attributes of an object might not be simple datatypes such as strings, dates or integers.</p>
|
||||
<p>The <code>Serializer</code> class is itself a type of <code>Field</code>, and can be used to represent relationships where one object type is nested inside another.</p>
|
||||
<pre><code>class UserSerializer(serializers.Serializer):
|
||||
<pre class="prettyprint lang-py"><code>class UserSerializer(serializers.Serializer):
|
||||
email = serializers.EmailField()
|
||||
username = serializers.CharField()
|
||||
|
||||
|
@ -192,7 +193,7 @@ class CommentSerializer(serializers.Serializer):
|
|||
<p>If you want to create a custom field, you'll probably want to override either one or both of the <code>.to_native()</code> and <code>.from_native()</code> methods. These two methods are used to convert between the intial datatype, and a primative, serializable datatype. Primative datatypes may be any of a number, string, date/time/datetime or None. They may also be any list or dictionary like object that only contains other primative objects.</p>
|
||||
<p>The <code>.to_native()</code> method is called to convert the initial datatype into a primative, serializable datatype. The <code>from_native()</code> method is called to restore a primative datatype into it's initial representation.</p>
|
||||
<p>Let's look at an example of serializing a class that represents an RGB color value:</p>
|
||||
<pre><code>class Color(object):
|
||||
<pre class="prettyprint lang-py"><code>class Color(object):
|
||||
"""
|
||||
A color represented in the RGB colorspace.
|
||||
"""
|
||||
|
@ -217,7 +218,7 @@ class ColourField(Field):
|
|||
</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><code>class ClassNameField(Field):
|
||||
<pre class="prettyprint lang-py"><code>class ClassNameField(Field):
|
||||
def field_to_native(self, obj, field_name):
|
||||
"""
|
||||
Serialize the object's class name, not an attribute of the object.
|
||||
|
@ -234,14 +235,14 @@ class ColourField(Field):
|
|||
<h1 id="modelserializers">ModelSerializers</h1>
|
||||
<p>Often you'll want serializer classes that map closely to model definitions.
|
||||
The <code>ModelSerializer</code> class lets you automatically create a Serializer class with fields that corrospond to the Model fields.</p>
|
||||
<pre><code>class AccountSerializer(ModelSerializer):
|
||||
<pre class="prettyprint lang-py"><code>class AccountSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Account
|
||||
</code></pre>
|
||||
<p><strong>[TODO: Explain model field to serializer field mapping in more detail]</strong></p>
|
||||
<h2 id="specifying-fields-explicitly">Specifying fields explicitly</h2>
|
||||
<p>You can add extra fields to a <code>ModelSerializer</code> or override the default fields by declaring fields on the class, just as you would for a <code>Serializer</code> class.</p>
|
||||
<pre><code>class AccountSerializer(ModelSerializer):
|
||||
<pre class="prettyprint lang-py"><code>class AccountSerializer(ModelSerializer):
|
||||
url = CharField(source='get_absolute_url', readonly=True)
|
||||
group = NaturalKeyField()
|
||||
|
||||
|
@ -259,7 +260,7 @@ The <code>ModelSerializer</code> class lets you automatically create a Serialize
|
|||
<h2 id="specifying-which-fields-should-be-included">Specifying which fields should be included</h2>
|
||||
<p>If you only want a subset of the default fields to be used in a model serializer, you can do so using <code>fields</code> or <code>exclude</code> options, just as you would with a <code>ModelForm</code>.</p>
|
||||
<p>For example:</p>
|
||||
<pre><code>class AccountSerializer(ModelSerializer):
|
||||
<pre class="prettyprint lang-py"><code>class AccountSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Account
|
||||
exclude = ('id',)
|
||||
|
@ -268,7 +269,7 @@ The <code>ModelSerializer</code> class lets you automatically create a Serialize
|
|||
<p><strong>[TODO: Possibly only allow .serialize(fields=…) in FixtureSerializer for backwards compatability, but remove for ModelSerializer]</strong></p>
|
||||
<h2 id="specifiying-nested-serialization">Specifiying nested serialization</h2>
|
||||
<p>The default <code>ModelSerializer</code> uses primary keys for relationships, but you can also easily generate nested representations using the <code>nested</code> option:</p>
|
||||
<pre><code>class AccountSerializer(ModelSerializer):
|
||||
<pre class="prettyprint lang-py"><code>class AccountSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Account
|
||||
exclude = ('id',)
|
||||
|
@ -279,7 +280,7 @@ The <code>ModelSerializer</code> class lets you automatically create a Serialize
|
|||
<p>The <code>nested</code> option may also be set by passing it to the <code>serialize()</code> method.</p>
|
||||
<p><strong>[TODO: Possibly only allow .serialize(nested=…) in FixtureSerializer]</strong></p>
|
||||
<h2 id="customising-the-default-fields-used-by-a-modelserializer">Customising the default fields used by a ModelSerializer</h2>
|
||||
<pre><code>class AccountSerializer(ModelSerializer):
|
||||
<pre class="prettyprint lang-py"><code>class AccountSerializer(ModelSerializer):
|
||||
class Meta:
|
||||
model = Account
|
||||
|
||||
|
@ -300,6 +301,7 @@ The <code>ModelSerializer</code> class lets you automatically create a Serialize
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -112,7 +113,7 @@
|
|||
<h1 id="settings">Settings</h1>
|
||||
<p>Configuration for REST framework is all namespaced inside the <code>API_SETTINGS</code> setting.</p>
|
||||
<p>For example your project's <code>settings.py</code> file might look like this:</p>
|
||||
<pre><code>API_SETTINGS = {
|
||||
<pre class="prettyprint lang-py"><code>API_SETTINGS = {
|
||||
'DEFAULT_RENDERERS': (
|
||||
'djangorestframework.renderers.YAMLRenderer',
|
||||
)
|
||||
|
@ -124,7 +125,7 @@
|
|||
<h2 id="accessing-settings">Accessing settings</h2>
|
||||
<p>If you need to access the values of REST framework's API settings in your project,
|
||||
you should use the <code>api_settings</code> object. For example.</p>
|
||||
<pre><code>from djangorestframework.settings import api_settings
|
||||
<pre class="prettyprint lang-py"><code>from djangorestframework.settings import api_settings
|
||||
|
||||
print api_settings.DEFAULT_AUTHENTICATION
|
||||
</code></pre>
|
||||
|
@ -132,7 +133,7 @@ print api_settings.DEFAULT_AUTHENTICATION
|
|||
<h2 id="default_renderers">DEFAULT_RENDERERS</h2>
|
||||
<p>A list or tuple of renderer classes, that determines the default set of renderers that may be used when returning a <code>Response</code> object.</p>
|
||||
<p>Default:</p>
|
||||
<pre><code>(
|
||||
<pre class="prettyprint lang-py"><code>(
|
||||
'djangorestframework.renderers.JSONRenderer',
|
||||
'djangorestframework.renderers.DocumentingHTMLRenderer'
|
||||
'djangorestframework.renderers.TemplateHTMLRenderer'
|
||||
|
@ -141,7 +142,7 @@ print api_settings.DEFAULT_AUTHENTICATION
|
|||
<h2 id="default_parsers">DEFAULT_PARSERS</h2>
|
||||
<p>A list or tuple of parser classes, that determines the default set of parsers used when accessing the <code>request.DATA</code> property.</p>
|
||||
<p>Default:</p>
|
||||
<pre><code>(
|
||||
<pre class="prettyprint lang-py"><code>(
|
||||
'djangorestframework.parsers.JSONParser',
|
||||
'djangorestframework.parsers.FormParser'
|
||||
)
|
||||
|
@ -149,7 +150,7 @@ print api_settings.DEFAULT_AUTHENTICATION
|
|||
<h2 id="default_authentication">DEFAULT_AUTHENTICATION</h2>
|
||||
<p>A list or tuple of authentication classes, that determines the default set of authenticators used when accessing the <code>request.user</code> or <code>request.auth</code> properties.</p>
|
||||
<p>Default:</p>
|
||||
<pre><code>(
|
||||
<pre class="prettyprint lang-py"><code>(
|
||||
'djangorestframework.authentication.SessionAuthentication',
|
||||
'djangorestframework.authentication.UserBasicAuthentication'
|
||||
)
|
||||
|
@ -199,6 +200,7 @@ print api_settings.DEFAULT_AUTHENTICATION
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -105,7 +106,7 @@
|
|||
<p>— <a href="http://www.ietf.org/rfc/rfc2324.txt">RFC 2324</a>, Hyper Text Coffee Pot Control Protocol</p>
|
||||
</blockquote>
|
||||
<p>Using bare status codes in your responses isn't recommended. REST framework includes a set of named constants that you can use to make more code more obvious and readable.</p>
|
||||
<pre><code>from djangorestframework import status
|
||||
<pre class="prettyprint lang-py"><code>from djangorestframework import status
|
||||
|
||||
def empty_view(self):
|
||||
content = {'please move along': 'nothing to see here'}
|
||||
|
@ -116,12 +117,12 @@ def empty_view(self):
|
|||
and <a href="http://tools.ietf.org/html/rfc6585">RFC 6585</a>.</p>
|
||||
<h2 id="informational-1xx">Informational - 1xx</h2>
|
||||
<p>This class of status code indicates a provisional response. There are no 1xx status codes used in REST framework by default.</p>
|
||||
<pre><code>HTTP_100_CONTINUE
|
||||
<pre class="prettyprint lang-py"><code>HTTP_100_CONTINUE
|
||||
HTTP_101_SWITCHING_PROTOCOLS
|
||||
</code></pre>
|
||||
<h2 id="successful-2xx">Successful - 2xx</h2>
|
||||
<p>This class of status code indicates that the client's request was successfully received, understood, and accepted.</p>
|
||||
<pre><code>HTTP_200_OK
|
||||
<pre class="prettyprint lang-py"><code>HTTP_200_OK
|
||||
HTTP_201_CREATED
|
||||
HTTP_202_ACCEPTED
|
||||
HTTP_203_NON_AUTHORITATIVE_INFORMATION
|
||||
|
@ -131,7 +132,7 @@ HTTP_206_PARTIAL_CONTENT
|
|||
</code></pre>
|
||||
<h2 id="redirection-3xx">Redirection - 3xx</h2>
|
||||
<p>This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.</p>
|
||||
<pre><code>HTTP_300_MULTIPLE_CHOICES
|
||||
<pre class="prettyprint lang-py"><code>HTTP_300_MULTIPLE_CHOICES
|
||||
HTTP_301_MOVED_PERMANENTLY
|
||||
HTTP_302_FOUND
|
||||
HTTP_303_SEE_OTHER
|
||||
|
@ -142,7 +143,7 @@ HTTP_307_TEMPORARY_REDIRECT
|
|||
</code></pre>
|
||||
<h2 id="client-error-4xx">Client Error - 4xx</h2>
|
||||
<p>The 4xx class of status code is intended for cases in which the client seems to have erred. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition.</p>
|
||||
<pre><code>HTTP_400_BAD_REQUEST
|
||||
<pre class="prettyprint lang-py"><code>HTTP_400_BAD_REQUEST
|
||||
HTTP_401_UNAUTHORIZED
|
||||
HTTP_402_PAYMENT_REQUIRED
|
||||
HTTP_403_FORBIDDEN
|
||||
|
@ -166,7 +167,7 @@ HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
|
|||
</code></pre>
|
||||
<h2 id="server-error-5xx">Server Error - 5xx</h2>
|
||||
<p>Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition.</p>
|
||||
<pre><code>HTTP_500_INTERNAL_SERVER_ERROR
|
||||
<pre class="prettyprint lang-py"><code>HTTP_500_INTERNAL_SERVER_ERROR
|
||||
HTTP_501_NOT_IMPLEMENTED
|
||||
HTTP_502_BAD_GATEWAY
|
||||
HTTP_503_SERVICE_UNAVAILABLE
|
||||
|
@ -182,6 +183,7 @@ HTTP_511_NETWORD_AUTHENTICATION_REQUIRED
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -102,6 +103,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -137,6 +138,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -10,6 +10,9 @@ body {
|
|||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
/* Preserve the spacing of the navbar across different screen sizes. */
|
||||
|
|
30
css/prettify.css
Normal file
30
css/prettify.css
Normal file
|
@ -0,0 +1,30 @@
|
|||
.com { color: #93a1a1; }
|
||||
.lit { color: #195f91; }
|
||||
.pun, .opn, .clo { color: #93a1a1; }
|
||||
.fun { color: #dc322f; }
|
||||
.str, .atv { color: #D14; }
|
||||
.kwd, .prettyprint .tag { color: #1e347b; }
|
||||
.typ, .atn, .dec, .var { color: teal; }
|
||||
.pln { color: #48484c; }
|
||||
|
||||
.prettyprint {
|
||||
padding: 8px;
|
||||
background-color: #f7f7f9;
|
||||
border: 1px solid #e1e1e8;
|
||||
}
|
||||
.prettyprint.linenums {
|
||||
-webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
||||
-moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
||||
box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
||||
}
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin: 0 0 0 33px; /* IE indents via margin-left */
|
||||
}
|
||||
ol.linenums li {
|
||||
padding-left: 12px;
|
||||
color: #bebec5;
|
||||
line-height: 20px;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
}
|
16
index.html
16
index.html
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -122,24 +123,24 @@
|
|||
<h2 id="installation">Installation</h2>
|
||||
<p><strong>WARNING: These instructions will only become valid once this becomes the master version</strong></p>
|
||||
<p>Install using <code>pip</code>, including any optional packages you want...</p>
|
||||
<pre><code>pip install djangorestframework
|
||||
<pre class="prettyprint lang-py"><code>pip install djangorestframework
|
||||
pip install markdown # Recommended if using the browseable API.
|
||||
pip install pyyaml # Required for yaml content-type support.
|
||||
</code></pre>
|
||||
<p>...or clone the project from github.</p>
|
||||
<pre><code>git clone git@github.com:tomchristie/django-rest-framework.git
|
||||
<pre class="prettyprint lang-py"><code>git clone git@github.com:tomchristie/django-rest-framework.git
|
||||
cd django-rest-framework
|
||||
pip install -r requirements.txt
|
||||
pip install -r optionals.txt
|
||||
</code></pre>
|
||||
<p>Add <code>djangorestframework</code> to your <code>INSTALLED_APPS</code>.</p>
|
||||
<pre><code>INSTALLED_APPS = (
|
||||
<pre class="prettyprint lang-py"><code>INSTALLED_APPS = (
|
||||
...
|
||||
'djangorestframework',
|
||||
)
|
||||
</code></pre>
|
||||
<p>If you're intending to use the browserable API you'll want to add REST framework's login and logout views. Add the following to your root <code>urls.py</code> file.</p>
|
||||
<pre><code>urlpatterns = patterns('',
|
||||
<pre class="prettyprint lang-py"><code>urlpatterns = patterns('',
|
||||
...
|
||||
url(r'^api-auth/', include('djangorestframework.urls', namespace='djangorestframework'))
|
||||
)
|
||||
|
@ -184,10 +185,10 @@ pip install -r optionals.txt
|
|||
<h2 id="development">Development</h2>
|
||||
<p>If you want to work on REST framework itself, clone the repository, then...</p>
|
||||
<p>Build the docs:</p>
|
||||
<pre><code>./mkdocs.py
|
||||
<pre class="prettyprint lang-py"><code>./mkdocs.py
|
||||
</code></pre>
|
||||
<p>Run the tests:</p>
|
||||
<pre><code>./djangorestframework/runtests/runtests.py
|
||||
<pre class="prettyprint lang-py"><code>./djangorestframework/runtests/runtests.py
|
||||
</code></pre>
|
||||
<h2 id="license">License</h2>
|
||||
<p>Copyright (c) 2011-2012, Tom Christie
|
||||
|
@ -217,6 +218,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
28
js/prettify.js
Normal file
28
js/prettify.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
|
||||
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
|
||||
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
|
||||
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
|
||||
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
|
||||
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
|
||||
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
|
||||
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
|
||||
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
|
||||
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
|
||||
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
|
||||
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
|
||||
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
|
||||
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
|
||||
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
|
||||
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
|
||||
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
|
||||
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
|
||||
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
|
||||
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
|
||||
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
|
||||
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
|
||||
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
|
||||
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
|
||||
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
|
||||
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
|
||||
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
|
||||
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -108,6 +109,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -99,43 +100,44 @@
|
|||
<h1 id="credits">Credits</h1>
|
||||
<p>The following people have helped make REST framework great.</p>
|
||||
<ul>
|
||||
<li>Tom Christie <tomchristie> </li>
|
||||
<li>Marko Tibold <markotibold></li>
|
||||
<li>Paul Bagwell <pbgwl></li>
|
||||
<li>Sébastien Piquemal <sebpiq></li>
|
||||
<li>Carmen Wick <cwick></li>
|
||||
<li>Alex Ehlke <aehlke></li>
|
||||
<li>Alen Mujezinovic <flashingpumpkin></li>
|
||||
<li>Carles Barrobés <txels></li>
|
||||
<li>Michael Fötsch <mfoetsch></li>
|
||||
<li>David Larlet <david></li>
|
||||
<li>Andrew Straw <astraw></li>
|
||||
<li>Zeth <zeth></li>
|
||||
<li>Fernando Zunino <fzunino></li>
|
||||
<li>Jens Alm <ulmus></li>
|
||||
<li>Craig Blaszczyk <jakul></li>
|
||||
<li>Garcia Solero <garciasolero></li>
|
||||
<li>Tom Drummond <devioustree></li>
|
||||
<li>Danilo Bargen <gwrtheyrn></li>
|
||||
<li>Andrew McCloud <amccloud></li>
|
||||
<li>Thomas Steinacher <thomasst></li>
|
||||
<li>Meurig Freeman <meurig></li>
|
||||
<li>Anthony Nemitz <anemitz></li>
|
||||
<li>Ewoud Kohl van Wijngaarden <ekohl></li>
|
||||
<li>Michael Ding <yandy></li>
|
||||
<li>Mjumbe Poe <mjumbewu></li>
|
||||
<li>Natim <natim></li>
|
||||
<li>Sebastian Żurek <sebzur></li>
|
||||
<li>Benoit C <dzen></li>
|
||||
<li>Chris Pickett <bunchesofdonald></li>
|
||||
<li>Ben Timby <btimby></li>
|
||||
<li>Michele Lazzeri <michelelazzeri-nextage></li>
|
||||
<li>Camille Harang <mammique></li>
|
||||
<li>Paul Oswald <poswald></li>
|
||||
<li>Sean C. Farley <scfarley></li>
|
||||
<li>Daniel Izquierdo <izquierdo></li>
|
||||
<li>Can Yavuz <tschan></li>
|
||||
<li>Shawn Lewis <shawnlewis></li>
|
||||
<li>Tom Christie - <a href="https://github.com/tomchristie">tomchristie</a> </li>
|
||||
<li>Marko Tibold - <a href="https://github.com/markotibold">markotibold</a></li>
|
||||
<li>Paul Bagwell - <a href="https://github.com/pbgwl">pbgwl</a></li>
|
||||
<li>Sébastien Piquemal - <a href="https://github.com/sebpiq">sebpiq</a></li>
|
||||
<li>Carmen Wick - <a href="https://github.com/cwick">cwick</a></li>
|
||||
<li>Alex Ehlke - <a href="https://github.com/aehlke">aehlke</a></li>
|
||||
<li>Alen Mujezinovic - <a href="https://github.com/flashingpumpkin">flashingpumpkin</a></li>
|
||||
<li>Carles Barrobés - <a href="https://github.com/txels">txels</a></li>
|
||||
<li>Michael Fötsch - <a href="https://github.com/mfoetsch">mfoetsch</a></li>
|
||||
<li>David Larlet - <a href="https://github.com/david">david</a></li>
|
||||
<li>Andrew Straw - <a href="https://github.com/astraw">astraw</a></li>
|
||||
<li>Zeth - <a href="https://github.com/zeth">zeth</a></li>
|
||||
<li>Fernando Zunino - <a href="https://github.com/fzunino">fzunino</a></li>
|
||||
<li>Jens Alm - <a href="https://github.com/ulmus">ulmus</a></li>
|
||||
<li>Craig Blaszczyk - <a href="https://github.com/jakul">jakul</a></li>
|
||||
<li>Garcia Solero - <a href="https://github.com/garciasolero">garciasolero</a></li>
|
||||
<li>Tom Drummond - <a href="https://github.com/devioustree">devioustree</a></li>
|
||||
<li>Danilo Bargen - <a href="https://github.com/gwrtheyrn">gwrtheyrn</a></li>
|
||||
<li>Andrew McCloud - <a href="https://github.com/amccloud">amccloud</a></li>
|
||||
<li>Thomas Steinacher - <a href="https://github.com/thomasst">thomasst</a></li>
|
||||
<li>Meurig Freeman - <a href="https://github.com/meurig">meurig</a></li>
|
||||
<li>Anthony Nemitz - <a href="https://github.com/anemitz">anemitz</a></li>
|
||||
<li>Ewoud Kohl van Wijngaarden - <a href="https://github.com/ekohl">ekohl</a></li>
|
||||
<li>Michael Ding - <a href="https://github.com/yandy">yandy</a></li>
|
||||
<li>Mjumbe Poe - <a href="https://github.com/mjumbewu">mjumbewu</a></li>
|
||||
<li>Natim - <a href="https://github.com/natim">natim</a></li>
|
||||
<li>Sebastian Żurek - <a href="https://github.com/sebzur">sebzur</a></li>
|
||||
<li>Benoit C - <a href="https://github.com/dzen">dzen</a></li>
|
||||
<li>Chris Pickett - <a href="https://github.com/bunchesofdonald">bunchesofdonald</a></li>
|
||||
<li>Ben Timby - <a href="https://github.com/btimby">btimby</a></li>
|
||||
<li>Michele Lazzeri - <a href="https://github.com/michelelazzeri-nextage">michelelazzeri-nextage</a></li>
|
||||
<li>Camille Harang - <a href="https://github.com/mammique">mammique</a></li>
|
||||
<li>Paul Oswald - <a href="https://github.com/poswald">poswald</a></li>
|
||||
<li>Sean C. Farley - <a href="https://github.com/scfarley">scfarley</a></li>
|
||||
<li>Daniel Izquierdo - <a href="https://github.com/izquierdo">izquierdo</a></li>
|
||||
<li>Can Yavuz - <a href="https://github.com/tschan">tschan</a></li>
|
||||
<li>Shawn Lewis - <a href="https://github.com/shawnlewis">shawnlewis</a></li>
|
||||
<li>Alec Perkins - <a href="https://github.com/alecperkins">alecperkins</a></li>
|
||||
</ul>
|
||||
<p>Many thanks to everyone who's contributed to the project.</p>
|
||||
<h2 id="additional-thanks">Additional thanks</h2>
|
||||
|
@ -146,7 +148,7 @@
|
|||
<p>To contact the author directly:</p>
|
||||
<ul>
|
||||
<li>twitter: <a href="http://twitter.com/_tomchristie">@_tomchristie</a></li>
|
||||
<li>mail: <a href="mailto:tom@tomchristie.com">tom@tomchristie.com</a></li>
|
||||
<li>email: <a href="mailto:tom@tomchristie.com">tom@tomchristie.com</a></li>
|
||||
</ul>
|
||||
</div><!--/span-->
|
||||
</div><!--/row-->
|
||||
|
@ -156,6 +158,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -112,6 +113,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -105,7 +106,7 @@
|
|||
<h2 id="overloading-the-http-method">Overloading the HTTP method</h2>
|
||||
<p><strong>TODO: Preamble.</strong> Note that this is the same strategy as is used in <a href="2">Ruby on Rails</a>.</p>
|
||||
<p>For example, given the following form:</p>
|
||||
<pre><code><form action="/news-items/5" method="POST">
|
||||
<pre class="prettyprint lang-py"><code><form action="/news-items/5" method="POST">
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
</form>
|
||||
</code></pre>
|
||||
|
@ -113,7 +114,7 @@
|
|||
<h2 id="overloading-the-http-content-type">Overloading the HTTP content type</h2>
|
||||
<p>Browser-based submission of content types other than form are supported by using form fields named <code>_content</code> and <code>_content_type</code>:</p>
|
||||
<p>For example, given the following form:</p>
|
||||
<pre><code><form action="/news-items/5" method="PUT">
|
||||
<pre class="prettyprint lang-py"><code><form action="/news-items/5" method="PUT">
|
||||
<input type="hidden" name="_content_type" value="application/json">
|
||||
<input name="_content" value="{'count': 1}">
|
||||
</form>
|
||||
|
@ -131,6 +132,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -108,26 +109,27 @@
|
|||
<p>This tutorial will walk you through the building blocks that make up REST framework. It'll take a little while to get through, but it'll give you a comprehensive understanding of how everything fits together.</p>
|
||||
<h2 id="setting-up-a-new-environment">Setting up a new environment</h2>
|
||||
<p>Before we do anything else we'll create a new virtual environment, using <a href="http://www.virtualenv.org/en/latest/index.html">virtualenv</a>. This will make sure our package configuration is keep nicely isolated from any other projects we're working on.</p>
|
||||
<pre><code>mkdir ~/env
|
||||
<pre class="prettyprint lang-bsh">
|
||||
mkdir ~/env
|
||||
virtualenv --no-site-packages ~/env/tutorial
|
||||
source ~/env/tutorial/bin/activate
|
||||
</code></pre>
|
||||
<p>Now that we're inside a virtualenv environment, we can install our package requirements.</p>
|
||||
<pre><code>pip install django
|
||||
<pre class="prettyprint lang-py"><code>pip install django
|
||||
pip install djangorestframework
|
||||
</code></pre>
|
||||
<p><strong>Note:</strong> To exit the virtualenv environment at any time, just type <code>deactivate</code>. For more information see the <a href="http://www.virtualenv.org/en/latest/index.html">virtualenv documentation</a>.</p>
|
||||
<h2 id="getting-started">Getting started</h2>
|
||||
<p>Okay, we're ready to get coding.
|
||||
To get started, let's create a new project to work with.</p>
|
||||
<pre><code>django-admin.py startproject tutorial
|
||||
<pre class="prettyprint lang-py"><code>django-admin.py startproject tutorial
|
||||
cd tutorial
|
||||
</code></pre>
|
||||
<p>Once that's done we can create an app that we'll use to create a simple Web API.</p>
|
||||
<pre><code>python manage.py startapp blog
|
||||
<pre class="prettyprint lang-py"><code>python manage.py startapp blog
|
||||
</code></pre>
|
||||
<p>The simplest way to get up and running will probably be to use an <code>sqlite3</code> database for the tutorial. Edit the <code>tutorial/settings.py</code> file, and set the default database <code>"ENGINE"</code> to <code>"sqlite3"</code>, and <code>"NAME"</code> to <code>"tmp.db"</code>.</p>
|
||||
<pre><code>DATABASES = {
|
||||
<pre class="prettyprint lang-py"><code>DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': 'tmp.db',
|
||||
|
@ -139,21 +141,21 @@ cd tutorial
|
|||
}
|
||||
</code></pre>
|
||||
<p>We'll also need to add our new <code>blog</code> app and the <code>djangorestframework</code> app to <code>INSTALLED_APPS</code>.</p>
|
||||
<pre><code>INSTALLED_APPS = (
|
||||
<pre class="prettyprint lang-py"><code>INSTALLED_APPS = (
|
||||
...
|
||||
'djangorestframework',
|
||||
'blog'
|
||||
)
|
||||
</code></pre>
|
||||
<p>We also need to wire up the root urlconf, in the <code>tutorial/urls.py</code> file, to include our blog views.</p>
|
||||
<pre><code>urlpatterns = patterns('',
|
||||
<pre class="prettyprint lang-py"><code>urlpatterns = patterns('',
|
||||
url(r'^', include('blog.urls')),
|
||||
)
|
||||
</code></pre>
|
||||
<p>Okay, we're ready to roll.</p>
|
||||
<h2 id="creating-a-model-to-work-with">Creating a model to work with</h2>
|
||||
<p>For the purposes of this tutorial we're going to start by creating a simple <code>Comment</code> model that is used to store comments against a blog post. Go ahead and edit the <code>blog</code> app's <code>models.py</code> file.</p>
|
||||
<pre><code>from django.db import models
|
||||
<pre class="prettyprint lang-py"><code>from django.db import models
|
||||
|
||||
class Comment(models.Model):
|
||||
email = models.EmailField()
|
||||
|
@ -161,11 +163,11 @@ class Comment(models.Model):
|
|||
created = models.DateTimeField(auto_now_add=True)
|
||||
</code></pre>
|
||||
<p>Don't forget to sync the database for the first time.</p>
|
||||
<pre><code>python manage.py syncdb
|
||||
<pre class="prettyprint lang-py"><code>python manage.py syncdb
|
||||
</code></pre>
|
||||
<h2 id="creating-a-serializer-class">Creating a Serializer class</h2>
|
||||
<p>We're going to create a simple Web API that we can use to edit these comment objects with. The first thing we need is a way of serializing and deserializing the objects into representations such as <code>json</code>. We do this by declaring serializers, that work very similarly to Django's forms. Create a file in the project named <code>serializers.py</code> and add the following.</p>
|
||||
<pre><code>from blog import models
|
||||
<pre class="prettyprint lang-py"><code>from blog import models
|
||||
from djangorestframework import serializers
|
||||
|
||||
class CommentSerializer(serializers.Serializer):
|
||||
|
@ -189,10 +191,10 @@ class CommentSerializer(serializers.Serializer):
|
|||
</p>
|
||||
<h2 id="working-with-serializers">Working with Serializers</h2>
|
||||
<p>Before we go any further we'll familiarise ourselves with using our new Serializer class. Let's drop into the Django shell.</p>
|
||||
<pre><code>python manage.py shell
|
||||
<pre class="prettyprint lang-py"><code>python manage.py shell
|
||||
</code></pre>
|
||||
<p>Okay, once we've got a few imports out of the way, we'd better create a few comments to work with.</p>
|
||||
<pre><code>from blog.models import Comment
|
||||
<pre class="prettyprint lang-py"><code>from blog.models import Comment
|
||||
from blog.serializers import CommentSerializer
|
||||
from djangorestframework.renderers import JSONRenderer
|
||||
from djangorestframework.parsers import JSONParser
|
||||
|
@ -205,20 +207,20 @@ c2.save()
|
|||
c3.save()
|
||||
</code></pre>
|
||||
<p>We've now got a few comment instances to play with. Let's take a look at serializing one of those instances.</p>
|
||||
<pre><code>serializer = CommentSerializer(instance=c1)
|
||||
<pre class="prettyprint lang-py"><code>serializer = CommentSerializer(instance=c1)
|
||||
serializer.data
|
||||
# {'email': u'leila@example.com', 'content': u'nothing to say', 'created': datetime.datetime(2012, 8, 22, 16, 20, 9, 822774, tzinfo=<UTC>)}
|
||||
</code></pre>
|
||||
<p>At this point we've translated the model instance into python native datatypes. To finalise the serialization process we render the data into <code>json</code>.</p>
|
||||
<pre><code>stream = JSONRenderer().render(serializer.data)
|
||||
<pre class="prettyprint lang-py"><code>stream = JSONRenderer().render(serializer.data)
|
||||
stream
|
||||
# '{"email": "leila@example.com", "content": "nothing to say", "created": "2012-08-22T16:20:09.822"}'
|
||||
</code></pre>
|
||||
<p>Deserialization is similar. First we parse a stream into python native datatypes... </p>
|
||||
<pre><code>data = JSONParser().parse(stream)
|
||||
<pre class="prettyprint lang-py"><code>data = JSONParser().parse(stream)
|
||||
</code></pre>
|
||||
<p>...then we restore those native datatypes into to a fully populated object instance.</p>
|
||||
<pre><code>serializer = CommentSerializer(data)
|
||||
<pre class="prettyprint lang-py"><code>serializer = CommentSerializer(data)
|
||||
serializer.is_valid()
|
||||
# True
|
||||
serializer.object
|
||||
|
@ -229,7 +231,7 @@ serializer.object
|
|||
<p>Let's see how we can write some API views using our new Serializer class.
|
||||
We'll start off by creating a subclass of HttpResponse that we can use to render any data we return into <code>json</code>.</p>
|
||||
<p>Edit the <code>blog/views.py</code> file, and add the following.</p>
|
||||
<pre><code>from blog.models import Comment
|
||||
<pre class="prettyprint lang-py"><code>from blog.models import Comment
|
||||
from blog.serializers import CommentSerializer
|
||||
from djangorestframework.renderers import JSONRenderer
|
||||
from djangorestframework.parsers import JSONParser
|
||||
|
@ -246,7 +248,7 @@ class JSONResponse(HttpResponse):
|
|||
super(JSONResponse, self).__init__(content, **kwargs)
|
||||
</code></pre>
|
||||
<p>The root of our API is going to be a view that supports listing all the existing comments, or creating a new comment.</p>
|
||||
<pre><code>def comment_root(request):
|
||||
<pre class="prettyprint lang-py"><code>def comment_root(request):
|
||||
"""
|
||||
List all comments, or create a new comment.
|
||||
"""
|
||||
|
@ -266,7 +268,7 @@ class JSONResponse(HttpResponse):
|
|||
return JSONResponse(serializer.error_data, status=400)
|
||||
</code></pre>
|
||||
<p>We'll also need a view which corrosponds to an individual comment, and can be used to retrieve, update or delete the comment.</p>
|
||||
<pre><code>def comment_instance(request, pk):
|
||||
<pre class="prettyprint lang-py"><code>def comment_instance(request, pk):
|
||||
"""
|
||||
Retrieve, update or delete a comment instance.
|
||||
"""
|
||||
|
@ -294,7 +296,7 @@ class JSONResponse(HttpResponse):
|
|||
return HttpResponse(status=204)
|
||||
</code></pre>
|
||||
<p>Finally we need to wire these views up, in the <code>tutorial/urls.py</code> file.</p>
|
||||
<pre><code>from django.conf.urls import patterns, url
|
||||
<pre class="prettyprint lang-py"><code>from django.conf.urls import patterns, url
|
||||
|
||||
urlpatterns = patterns('blog.views',
|
||||
url(r'^$', 'comment_root'),
|
||||
|
@ -317,6 +319,7 @@ urlpatterns = patterns('blog.views',
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -107,12 +108,12 @@
|
|||
Let's introduce a couple of essential building blocks.</p>
|
||||
<h2 id="request-objects">Request objects</h2>
|
||||
<p>REST framework intoduces a <code>Request</code> object that extends the regular <code>HttpRequest</code>, and provides more flexible request parsing. The core functionality of the <code>Request</code> object is the <code>request.DATA</code> attribute, which is similar to <code>request.POST</code>, but more useful for working with Web APIs.</p>
|
||||
<pre><code>request.POST # Only handles form data. Only works for 'POST' method.
|
||||
<pre class="prettyprint lang-py"><code>request.POST # Only handles form data. Only works for 'POST' method.
|
||||
request.DATA # Handles arbitrary data. Works any HTTP request with content.
|
||||
</code></pre>
|
||||
<h2 id="response-objects">Response objects</h2>
|
||||
<p>REST framework also introduces a <code>Response</code> object, which is a type of <code>TemplateResponse</code> that takes unrendered content and uses content negotiation to determine the correct content type to return to the client.</p>
|
||||
<pre><code>return Response(data) # Renders to content type as requested by the client.
|
||||
<pre class="prettyprint lang-py"><code>return Response(data) # Renders to content type as requested by the client.
|
||||
</code></pre>
|
||||
<h2 id="status-codes">Status codes</h2>
|
||||
<p>Using numeric HTTP status codes in your views doesn't always make for obvious reading, and it's easy to not notice if you get an error code wrong. REST framework provides more explicit identifiers for each status code, such as <code>HTTP_400_BAD_REQUEST</code> in the <code>status</code> module. It's a good idea to use these throughout rather than using numeric identifiers.</p>
|
||||
|
@ -127,7 +128,7 @@ request.DATA # Handles arbitrary data. Works any HTTP request with content.
|
|||
<h2 id="pulling-it-all-together">Pulling it all together</h2>
|
||||
<p>Okay, let's go ahead and start using these new components to write a few views. </p>
|
||||
<p>We don't need our <code>JSONResponse</code> class anymore, so go ahead and delete that. Once that's done we can start refactoring our views slightly.</p>
|
||||
<pre><code>from blog.models import Comment
|
||||
<pre class="prettyprint lang-py"><code>from blog.models import Comment
|
||||
from blog.serializers import CommentSerializer
|
||||
from djangorestframework import status
|
||||
from djangorestframework.decorators import api_view
|
||||
|
@ -153,7 +154,7 @@ def comment_root(request):
|
|||
return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST)
|
||||
</code></pre>
|
||||
<p>Our instance view is an improvement over the previous example. It's a little more concise, and the code now feels very similar to if we were working with the Forms API. We're also using named status codes, which makes the response meanings more obvious.</p>
|
||||
<pre><code>@api_view(['GET', 'PUT', 'DELETE'])
|
||||
<pre class="prettyprint lang-py"><code>@api_view(['GET', 'PUT', 'DELETE'])
|
||||
def comment_instance(request, pk):
|
||||
"""
|
||||
Retrieve, update or delete a comment instance.
|
||||
|
@ -185,13 +186,13 @@ def comment_instance(request, pk):
|
|||
<h2 id="adding-optional-format-suffixes-to-our-urls">Adding optional format suffixes to our URLs</h2>
|
||||
<p>To take advantage of the fact that our responses are no longer hardwired to a single content type let's add support for format suffixes to our API endpoints. Using format suffixes gives us URLs that explicitly refer to a given format, and means our API will be able to handle URLs such as <a href="http://example.com/api/items/4.json">http://example.com/api/items/4.json</a>.</p>
|
||||
<p>Start by adding a <code>format</code> keyword argument to both of the views, like so.</p>
|
||||
<pre><code>def comment_root(request, format=None):
|
||||
<pre class="prettyprint lang-py"><code>def comment_root(request, format=None):
|
||||
</code></pre>
|
||||
<p>and</p>
|
||||
<pre><code>def comment_instance(request, pk, format=None):
|
||||
<pre class="prettyprint lang-py"><code>def comment_instance(request, pk, format=None):
|
||||
</code></pre>
|
||||
<p>Now update the <code>urls.py</code> file slightly, to append a set of <code>format_suffix_patterns</code> in addition to the existing URLs.</p>
|
||||
<pre><code>from django.conf.urls import patterns, url
|
||||
<pre class="prettyprint lang-py"><code>from django.conf.urls import patterns, url
|
||||
from djangorestframework.urlpatterns import format_suffix_patterns
|
||||
|
||||
urlpatterns = patterns('blogpost.views',
|
||||
|
@ -218,6 +219,7 @@ urlpatterns = format_suffix_patterns(urlpatterns)
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -101,7 +102,7 @@
|
|||
<p>We can also write our API views using class based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>.</p>
|
||||
<h2 id="rewriting-our-api-using-class-based-views">Rewriting our API using class based views</h2>
|
||||
<p>We'll start by rewriting the root view as a class based view. All this involves is a little bit of refactoring.</p>
|
||||
<pre><code>from blog.models import Comment
|
||||
<pre class="prettyprint lang-py"><code>from blog.models import Comment
|
||||
from blog.serializers import CommentSerializer
|
||||
from django.http import Http404
|
||||
from djangorestframework.views import APIView
|
||||
|
@ -128,7 +129,7 @@ class CommentRoot(APIView):
|
|||
comment_root = CommentRoot.as_view()
|
||||
</code></pre>
|
||||
<p>So far, so good. It looks pretty similar to the previous case, but we've got better seperation between the different HTTP methods. We'll also need to update the instance view. </p>
|
||||
<pre><code>class CommentInstance(APIView):
|
||||
<pre class="prettyprint lang-py"><code>class CommentInstance(APIView):
|
||||
"""
|
||||
Retrieve, update or delete a comment instance.
|
||||
"""
|
||||
|
@ -166,7 +167,7 @@ Okay, we're done. If you run the development server everything should be workin
|
|||
<p>One of the big wins of using class based views is that it allows us to easily compose reusable bits of behaviour.</p>
|
||||
<p>The create/retrieve/update/delete operations that we've been using so far are going to be pretty simliar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes.</p>
|
||||
<p>Let's take a look at how we can compose our views by using the mixin classes.</p>
|
||||
<pre><code>from blog.models import Comment
|
||||
<pre class="prettyprint lang-py"><code>from blog.models import Comment
|
||||
from blog.serializers import CommentSerializer
|
||||
from djangorestframework import mixins
|
||||
from djangorestframework import generics
|
||||
|
@ -187,7 +188,7 @@ comment_root = CommentRoot.as_view()
|
|||
</code></pre>
|
||||
<p>We'll take a moment to examine exactly what's happening here - We're building our view using <code>MultipleObjectBaseView</code>, and adding in <code>ListModelMixin</code> and <code>CreateModelMixin</code>.</p>
|
||||
<p>The base class provides the core functionality, and the mixin classes provide the <code>.list()</code> and <code>.create()</code> actions. We're then explictly binding the <code>get</code> and <code>post</code> methods to the appropriate actions. Simple enough stuff so far.</p>
|
||||
<pre><code>class CommentInstance(mixins.RetrieveModelMixin,
|
||||
<pre class="prettyprint lang-py"><code>class CommentInstance(mixins.RetrieveModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
generics.SingleObjectBaseView):
|
||||
|
@ -208,7 +209,7 @@ comment_instance = CommentInstance.as_view()
|
|||
<p>Pretty similar. This time we're using the <code>SingleObjectBaseView</code> class to provide the core functionality, and adding in mixins to provide the <code>.retrieve()</code>, <code>.update()</code> and <code>.destroy()</code> actions.</p>
|
||||
<h2 id="using-generic-class-based-views">Using generic class based views</h2>
|
||||
<p>Using the mixin classes we've rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use.</p>
|
||||
<pre><code>from blog.models import Comment
|
||||
<pre class="prettyprint lang-py"><code>from blog.models import Comment
|
||||
from blog.serializers import CommentSerializer
|
||||
from djangorestframework import generics
|
||||
|
||||
|
@ -234,6 +235,7 @@ comment_instance = CommentInstance.as_view()
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -102,6 +103,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -108,6 +109,7 @@
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/prettify.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="http://tomchristie.github.com/django-rest-framework/css/drf-styles.css" rel="stylesheet">
|
||||
|
@ -15,7 +16,7 @@
|
|||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<body>
|
||||
<body onload="prettyPrint()">
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -96,7 +97,7 @@
|
|||
|
||||
<div id="main-content" class="span9">
|
||||
<p>serializers.py</p>
|
||||
<pre><code>class BlogPostSerializer(URLModelSerializer):
|
||||
<pre class="prettyprint lang-py"><code>class BlogPostSerializer(URLModelSerializer):
|
||||
class Meta:
|
||||
model = BlogPost
|
||||
|
||||
|
@ -105,7 +106,7 @@ class CommentSerializer(URLModelSerializer):
|
|||
model = Comment
|
||||
</code></pre>
|
||||
<p>resources.py</p>
|
||||
<pre><code>class BlogPostResource(ModelResource):
|
||||
<pre class="prettyprint lang-py"><code>class BlogPostResource(ModelResource):
|
||||
serializer_class = BlogPostSerializer
|
||||
model = BlogPost
|
||||
permissions = [AdminOrAnonReadonly()]
|
||||
|
@ -118,7 +119,7 @@ class CommentResource(ModelResource):
|
|||
throttles = [AnonThrottle(rate='5/min')]
|
||||
</code></pre>
|
||||
<p>Now that we're using Resources rather than Views, we don't need to design the urlconf ourselves. The conventions for wiring up resources into views and urls are handled automatically. All we need to do is register the appropriate resources with a router, and let it do the rest. Here's our re-wired <code>urls.py</code> file.</p>
|
||||
<pre><code>from blog import resources
|
||||
<pre class="prettyprint lang-py"><code>from blog import resources
|
||||
from djangorestframework.routers import DefaultRouter
|
||||
|
||||
router = DefaultRouter()
|
||||
|
@ -145,6 +146,7 @@ urlpatterns = router.urlpatterns
|
|||
================================================== -->
|
||||
<!-- Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/jquery-1.8.1-min.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/prettify.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-dropdown.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-scrollspy.js"></script>
|
||||
<script src="http://tomchristie.github.com/django-rest-framework/js/bootstrap-collapse.js"></script>
|
||||
|
|
Loading…
Reference in New Issue
Block a user