Update documentation

This commit is contained in:
Xavier Ordoquy 2015-01-10 10:41:12 +01:00
parent c1e4ec0c64
commit d8dbd86790
20 changed files with 104 additions and 13 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -487,7 +487,7 @@
<p>If no class authenticates, <code>request.user</code> will be set to an instance of <code>django.contrib.auth.models.AnonymousUser</code>, and <code>request.auth</code> will be set to <code>None</code>.</p> <p>If no class authenticates, <code>request.user</code> will be set to an instance of <code>django.contrib.auth.models.AnonymousUser</code>, and <code>request.auth</code> will be set to <code>None</code>.</p>
<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> <p>The value of <code>request.user</code> and <code>request.auth</code> for unauthenticated requests can be modified using the <code>UNAUTHENTICATED_USER</code> and <code>UNAUTHENTICATED_TOKEN</code> settings.</p>
<h2 id="setting-the-authentication-scheme">Setting the authentication scheme</h2> <h2 id="setting-the-authentication-scheme">Setting the authentication scheme</h2>
<p>The default authentication schemes may be set globally, using the <code>DEFAULT_AUTHENTICATION</code> setting. For example.</p> <p>The default authentication schemes may be set globally, using the <code>DEFAULT_AUTHENTICATION_CLASSES</code> setting. For example.</p>
<pre><code>REST_FRAMEWORK = { <pre><code>REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ( 'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.BasicAuthentication',
@ -672,7 +672,7 @@ python manage.py createsuperuser
'provider.oauth2', 'provider.oauth2',
) )
</code></pre> </code></pre>
<p>Then add <code>OAuth2Authentication</code> to your global <code>DEFAULT_AUTHENTICATION</code> setting:</p> <p>Then add <code>OAuth2Authentication</code> to your global <code>DEFAULT_AUTHENTICATION_CLASSES</code> setting:</p>
<pre><code>'DEFAULT_AUTHENTICATION_CLASSES': ( <pre><code>'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.OAuth2Authentication', 'rest_framework.authentication.OAuth2Authentication',
), ),

View File

@ -442,7 +442,7 @@
<li>Django's <code>PermissionDenied</code> exception.</li> <li>Django's <code>PermissionDenied</code> exception.</li>
</ul> </ul>
<p>In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.</p> <p>In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.</p>
<p>By default all error responses will include a key <code>detail</code> in the body of the response, but other keys may also be included.</p> <p>Most error responses will include a key <code>detail</code> in the body of the response.</p>
<p>For example, the following request:</p> <p>For example, the following request:</p>
<pre><code>DELETE http://api.example.com/foo/bar HTTP/1.1 <pre><code>DELETE http://api.example.com/foo/bar HTTP/1.1
Accept: application/json Accept: application/json
@ -454,6 +454,14 @@ Content-Length: 42
{"detail": "Method 'DELETE' not allowed."} {"detail": "Method 'DELETE' not allowed."}
</code></pre> </code></pre>
<p>Validation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the "non_field_errors" key, or whatever string value has been set for the <code>NON_FIELD_ERRORS_KEY</code> setting.</p>
<p>Any example validation error might look like this:</p>
<pre><code>HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 94
{"amount": ["A valid integer is required."], "description": ["This field may not be blank."]}
</code></pre>
<h2 id="custom-exception-handling">Custom exception handling</h2> <h2 id="custom-exception-handling">Custom exception handling</h2>
<p>You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.</p> <p>You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.</p>
<p>The function must take a single argument, which is the exception to be handled, and should either return a <code>Response</code> object, or return <code>None</code> if the exception cannot be handled. If the handler returns <code>None</code> then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.</p> <p>The function must take a single argument, which is the exception to be handled, and should either return a <code>Response</code> object, or return <code>None</code> if the exception cannot be handled. If the handler returns <code>None</code> then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.</p>

View File

@ -595,6 +595,7 @@
<h3 id="required"><code>required</code></h3> <h3 id="required"><code>required</code></h3>
<p>Normally an error will be raised if a field is not supplied during deserialization. <p>Normally an error will be raised if a field is not supplied during deserialization.
Set to false if this field is not required to be present during deserialization.</p> Set to false if this field is not required to be present during deserialization.</p>
<p>Setting this to <code>False</code> also allows the object attribute or dictionary key to be omitted from output when serializing the instance. If the key is not present it will simply not be included in the output representation.</p>
<p>Defaults to <code>True</code>.</p> <p>Defaults to <code>True</code>.</p>
<h3 id="allow_null"><code>allow_null</code></h3> <h3 id="allow_null"><code>allow_null</code></h3>
<p>Normally an error will be raised if <code>None</code> is passed to a serializer field. Set this keyword argument to <code>True</code> if <code>None</code> should be considered a valid value.</p> <p>Normally an error will be raised if <code>None</code> is passed to a serializer field. Set this keyword argument to <code>True</code> if <code>None</code> should be considered a valid value.</p>
@ -879,7 +880,7 @@ class UserSerializer(serializers.ModelSerializer):
class ColorField(serializers.Field): class ColorField(serializers.Field):
""" """
Color objects are serialized into "rgb(#, #, #)" notation. Color objects are serialized into 'rgb(#, #, #)' notation.
""" """
def to_representation(self, obj): def to_representation(self, obj):
return "rgb(%d, %d, %d)" % (obj.red, obj.green, obj.blue) return "rgb(%d, %d, %d)" % (obj.red, obj.green, obj.blue)

View File

@ -702,6 +702,7 @@ class ProductFilter(django_filters.FilterSet):
queryset = User.objects.all() queryset = User.objects.all()
serializer_class = UserSerializer serializer_class = UserSerializer
filter_backends = (filters.OrderingFilter,) filter_backends = (filters.OrderingFilter,)
ordering_fields = ('username', 'email')
ordering = ('username',) ordering = ('username',)
</code></pre> </code></pre>
<p>The <code>ordering</code> attribute may be either a string or a list/tuple of strings.</p> <p>The <code>ordering</code> attribute may be either a string or a list/tuple of strings.</p>

View File

@ -428,6 +428,16 @@ def comment_list(request, format=None):
</code></pre> </code></pre>
<p>The name of the kwarg used may be modified by using the <code>FORMAT_SUFFIX_KWARG</code> setting.</p> <p>The name of the kwarg used may be modified by using the <code>FORMAT_SUFFIX_KWARG</code> setting.</p>
<p>Also note that <code>format_suffix_patterns</code> does not support descending into <code>include</code> URL patterns.</p> <p>Also note that <code>format_suffix_patterns</code> does not support descending into <code>include</code> URL patterns.</p>
<h3 id="using-with-i18n_patterns">Using with <code>i18n_patterns</code></h3>
<p>If using the <code>i18n_patterns</code> function provided by Django, as well as <code>format_suffix_patterns</code> you should make sure that the <code>i18n_patterns</code> function is applied as the final, or outermost function. For example:</p>
<pre><code>url patterns = [
]
urlpatterns = i18n_patterns(
format_suffix_patterns(urlpatterns, allowed=['json', 'html'])
)
</code></pre>
<hr /> <hr />
<h2 id="accept-headers-vs-format-suffixes">Accept headers vs. format suffixes</h2> <h2 id="accept-headers-vs-format-suffixes">Accept headers vs. format suffixes</h2>
<p>There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that <code>HTTP Accept</code> headers should always be used instead.</p> <p>There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that <code>HTTP Accept</code> headers should always be used instead.</p>

View File

@ -666,6 +666,7 @@ class UserList(generics.ListCreateAPIView):
<hr /> <hr />
<h1 id="mixins">Mixins</h1> <h1 id="mixins">Mixins</h1>
<p>The mixin classes provide the actions that are used to provide the basic view behavior. Note that the mixin classes provide action methods rather than defining the handler methods, such as <code>.get()</code> and <code>.post()</code>, directly. This allows for more flexible composition of behavior.</p> <p>The mixin classes provide the actions that are used to provide the basic view behavior. Note that the mixin classes provide action methods rather than defining the handler methods, such as <code>.get()</code> and <code>.post()</code>, directly. This allows for more flexible composition of behavior.</p>
<p>The mixin classes can be imported from <code>rest_framework.mixins</code>.</p>
<h2 id="listmodelmixin">ListModelMixin</h2> <h2 id="listmodelmixin">ListModelMixin</h2>
<p>Provides a <code>.list(request, *args, **kwargs)</code> method, that implements listing a queryset.</p> <p>Provides a <code>.list(request, *args, **kwargs)</code> method, that implements listing a queryset.</p>
<p>If the queryset is populated, this returns a <code>200 OK</code> response, with a serialized representation of the queryset as the body of the response. The response data may optionally be paginated.</p> <p>If the queryset is populated, this returns a <code>200 OK</code> response, with a serialized representation of the queryset as the body of the response. The response data may optionally be paginated.</p>
@ -688,6 +689,7 @@ class UserList(generics.ListCreateAPIView):
<hr /> <hr />
<h1 id="concrete-view-classes">Concrete View Classes</h1> <h1 id="concrete-view-classes">Concrete View Classes</h1>
<p>The following classes are the concrete generic views. If you're using generic views this is normally the level you'll be working at unless you need heavily customized behavior.</p> <p>The following classes are the concrete generic views. If you're using generic views this is normally the level you'll be working at unless you need heavily customized behavior.</p>
<p>The view classes can be imported from <code>rest_framework.generics</code>.</p>
<h2 id="createapiview">CreateAPIView</h2> <h2 id="createapiview">CreateAPIView</h2>
<p>Used for <strong>create-only</strong> endpoints.</p> <p>Used for <strong>create-only</strong> endpoints.</p>
<p>Provides a <code>post</code> method handler.</p> <p>Provides a <code>post</code> method handler.</p>

View File

@ -664,6 +664,7 @@ class Track(models.Model):
<ul> <ul>
<li><code>view_name</code> - The view name that should be used as the target of the relationship. If you're using <a href="http://www.django-rest-framework.org/api-guide/routers#defaultrouter">the standard router classes</a> this will be a string with the format <code>&lt;model_name&gt;-detail</code>. <strong>required</strong>.</li> <li><code>view_name</code> - The view name that should be used as the target of the relationship. If you're using <a href="http://www.django-rest-framework.org/api-guide/routers#defaultrouter">the standard router classes</a> this will be a string with the format <code>&lt;model_name&gt;-detail</code>. <strong>required</strong>.</li>
<li><code>lookup_field</code> - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is <code>'pk'</code>.</li> <li><code>lookup_field</code> - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is <code>'pk'</code>.</li>
<li><code>lookup_url_kwarg</code> - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as <code>lookup_field</code>.</li>
<li><code>format</code> - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the <code>format</code> argument.</li> <li><code>format</code> - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the <code>format</code> argument.</li>
</ul> </ul>
<hr /> <hr />

View File

@ -475,6 +475,32 @@ urlpatterns = router.urls
</code></pre> </code></pre>
<p>This means you'll need to explicitly set the <code>base_name</code> argument when registering the viewset, as it could not be automatically determined from the model name.</p> <p>This means you'll need to explicitly set the <code>base_name</code> argument when registering the viewset, as it could not be automatically determined from the model name.</p>
<hr /> <hr />
<h3 id="using-include-with-routers">Using <code>include</code> with routers</h3>
<p>The <code>.urls</code> attribute on a router instance is simply a standard list of URL patterns. There are a number of different styles for how you can include these URLs.</p>
<p>For example, you can append <code>router.urls</code> to a list of existing views…</p>
<pre><code>router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = [
url(r'^forgot-password/$, ForgotPasswordFormView.as_view(),
]
urlpatterns += router.urls
</code></pre>
<p>Alternatively you can use Django's <code>include</code> function, like so…</p>
<pre><code>urlpatterns = [
url(r'^forgot-password/$, ForgotPasswordFormView.as_view(),
url(r'^', include(router.urls))
]
</code></pre>
<p>Router URL patterns can also be namespaces.</p>
<pre><code>urlpatterns = [
url(r'^forgot-password/$, ForgotPasswordFormView.as_view(),
url(r'^api/', include(router.urls, namespace='api'))
]
</code></pre>
<p>If using namespacing with hyperlinked serializers you'll also need to ensure that any <code>view_name</code> parameters on the serializers correctly reflect the namespace. In the example above you'd need to include a parameter such as <code>view_name='api:user-detail'</code> for serializer fields hyperlinked to the user detail view.</p>
<h3 id="extra-link-and-actions">Extra link and actions</h3> <h3 id="extra-link-and-actions">Extra link and actions</h3>
<p>Any methods on the viewset decorated with <code>@detail_route</code> or <code>@list_route</code> will also be routed. <p>Any methods on the viewset decorated with <code>@detail_route</code> or <code>@list_route</code> will also be routed.
For example, given a method like this on the <code>UserViewSet</code> class:</p> For example, given a method like this on the <code>UserViewSet</code> class:</p>
@ -492,6 +518,22 @@ class UserViewSet(ModelViewSet):
<ul> <ul>
<li>URL pattern: <code>^users/{pk}/set_password/$</code> Name: <code>'user-set-password'</code></li> <li>URL pattern: <code>^users/{pk}/set_password/$</code> Name: <code>'user-set-password'</code></li>
</ul> </ul>
<p>If you do not want to use the default URL generated for your custom action, you can instead use the url_path parameter to customize it.</p>
<p>For example, if you want to change the URL for our custom action to <code>^users/{pk}/change-password/$</code>, you could write:</p>
<pre><code>from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import detail_route
class UserViewSet(ModelViewSet):
...
@detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf], url_path='change-password')
def set_password(self, request, pk=None):
...
</code></pre>
<p>The above example would now generate the following URL pattern:</p>
<ul>
<li>URL pattern: <code>^users/{pk}/change-password/$</code> Name: <code>'user-change-password'</code></li>
</ul>
<p>For more information see the viewset documentation on <a href="../../viewsets.html#marking-extra-actions-for-routing">marking extra actions for routing</a>.</p> <p>For more information see the viewset documentation on <a href="../../viewsets.html#marking-extra-actions-for-routing">marking extra actions for routing</a>.</p>
<h1 id="api-guide">API Guide</h1> <h1 id="api-guide">API Guide</h1>
<h2 id="simplerouter">SimpleRouter</h2> <h2 id="simplerouter">SimpleRouter</h2>

View File

@ -868,7 +868,7 @@ serializer.errors
has_support_contract=validated_data['profile']['has_support_contract'] has_support_contract=validated_data['profile']['has_support_contract']
) )
</code></pre> </code></pre>
<p>For more details on this approach see the Django documentation on <a href="../../model-managers">model managers</a>, and <a href="../../encapsulation-blogpost">this blogpost on using model and manger classes</a>.</p> <p>For more details on this approach see the Django documentation on <a href="../../model-managers">model managers</a>, and <a href="../../encapsulation-blogpost">this blogpost on using model and manager classes</a>.</p>
<h2 id="dealing-with-multiple-objects">Dealing with multiple objects</h2> <h2 id="dealing-with-multiple-objects">Dealing with multiple objects</h2>
<p>The <code>Serializer</code> class can also handle serializing or deserializing lists of objects.</p> <p>The <code>Serializer</code> class can also handle serializing or deserializing lists of objects.</p>
<h4 id="serializing-multiple-objects">Serializing multiple objects</h4> <h4 id="serializing-multiple-objects">Serializing multiple objects</h4>

BIN
img/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

BIN
img/sponsors/.DS_Store vendored

Binary file not shown.

View File

@ -502,7 +502,7 @@
<p>REST framework requires the following:</p> <p>REST framework requires the following:</p>
<ul> <ul>
<li>Python (2.6.5+, 2.7, 3.2, 3.3, 3.4)</li> <li>Python (2.6.5+, 2.7, 3.2, 3.3, 3.4)</li>
<li>Django (1.4.11+, 1.5.5+, 1.6, 1.7)</li> <li>Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7)</li>
</ul> </ul>
<p>The following packages are optional:</p> <p>The following packages are optional:</p>
<ul> <ul>
@ -655,7 +655,7 @@ Framework.</p>
<p>If you believe youve found something in Django REST framework which has security implications, please <strong>do not raise the issue in a public forum</strong>.</p> <p>If you believe youve found something in Django REST framework which has security implications, please <strong>do not raise the issue in a public forum</strong>.</p>
<p>Send a description of the issue via email to <a href="mailto:rest-framework-security@googlegroups.com">rest-framework-security@googlegroups.com</a>. The project maintainers will then work with you to resolve any issues where required, prior to any public disclosure.</p> <p>Send a description of the issue via email to <a href="mailto:rest-framework-security@googlegroups.com">rest-framework-security@googlegroups.com</a>. The project maintainers will then work with you to resolve any issues where required, prior to any public disclosure.</p>
<h2 id="license">License</h2> <h2 id="license">License</h2>
<p>Copyright (c) 2011-2014, Tom Christie <p>Copyright (c) 2011-2015, Tom Christie
All rights reserved.</p> All rights reserved.</p>
<p>Redistribution and use in source and binary forms, with or without <p>Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:</p> modification, are permitted provided that the following conditions are met:</p>

View File

@ -472,9 +472,9 @@ ExampleSerializer(data=request.DATA, files=request.FILES)
</ol> </ol>
<p>The resulting API changes are further detailed below.</p> <p>The resulting API changes are further detailed below.</p>
<h4 id="the-create-and-update-methods">The <code>.create()</code> and <code>.update()</code> methods.</h4> <h4 id="the-create-and-update-methods">The <code>.create()</code> and <code>.update()</code> methods.</h4>
<p>The <code>.restore_object()</code> method is now replaced with two separate methods, <code>.create()</code> and <code>.update()</code>.</p> <p>The <code>.restore_object()</code> method is now removed, and we instead have two separate methods, <code>.create()</code> and <code>.update()</code>. These methods work slightly different to the previous <code>.restore_object()</code>.</p>
<p>These methods also replace the optional <code>.save_object()</code> method, which no longer exists.</p>
<p>When using the <code>.create()</code> and <code>.update()</code> methods you should both create <em>and save</em> the object instance. This is in contrast to the previous <code>.restore_object()</code> behavior that would instantiate the object but not save it.</p> <p>When using the <code>.create()</code> and <code>.update()</code> methods you should both create <em>and save</em> the object instance. This is in contrast to the previous <code>.restore_object()</code> behavior that would instantiate the object but not save it.</p>
<p>These methods also replace the optional <code>.save_object()</code> method, which no longer exists.</p>
<p>The following example from the tutorial previously used <code>restore_object()</code> to handle both creating and updating object instances.</p> <p>The following example from the tutorial previously used <code>restore_object()</code> to handle both creating and updating object instances.</p>
<pre><code>def restore_object(self, attrs, instance=None): <pre><code>def restore_object(self, attrs, instance=None):
if instance: if instance:
@ -1136,6 +1136,7 @@ amount = serializers.DecimalField(
<li>The serializer <code>ChoiceField</code> does not currently display nested choices, as was the case in 2.4. This will be address as part of 3.1.</li> <li>The serializer <code>ChoiceField</code> does not currently display nested choices, as was the case in 2.4. This will be address as part of 3.1.</li>
<li>Due to the new templated form rendering, the 'widget' option is no longer valid. This means there's no easy way of using third party "autocomplete" widgets for rendering select inputs that contain a large number of choices. You'll either need to use a regular select or a plain text input. We may consider addressing this in 3.1 or 3.2 if there's sufficient demand.</li> <li>Due to the new templated form rendering, the 'widget' option is no longer valid. This means there's no easy way of using third party "autocomplete" widgets for rendering select inputs that contain a large number of choices. You'll either need to use a regular select or a plain text input. We may consider addressing this in 3.1 or 3.2 if there's sufficient demand.</li>
<li>Some of the default validation error messages were rewritten and might no longer be pre-translated. You can still <a href="https://docs.djangoproject.com/en/dev/topics/i18n/translation/#localization-how-to-create-language-files">create language files with Django</a> if you wish to localize them.</li> <li>Some of the default validation error messages were rewritten and might no longer be pre-translated. You can still <a href="https://docs.djangoproject.com/en/dev/topics/i18n/translation/#localization-how-to-create-language-files">create language files with Django</a> if you wish to localize them.</li>
<li><code>APIException</code> subclasses could previously take could previously take any arbitrary type in the <code>detail</code> argument. These exceptions now use translatable text strings, and as a result call <code>force_text</code> on the <code>detail</code> argument, which <em>must be a string</em>. If you need complex arguments to an <code>APIException</code> class, you should subclass it and override the <code>__init__()</code> method. Typically you'll instead want to use a custom exception handler to provide for non-standard error responses.</li>
</ul> </ul>
<hr /> <hr />
<h2 id="whats-coming-next">What's coming next</h2> <h2 id="whats-coming-next">What's coming next</h2>

View File

@ -432,6 +432,8 @@ The following people are the current maintenance team. Please checkmark your nam
#### New members. #### New members.
If you wish to be considered for this or a future date, please comment against this or subsequent issues. If you wish to be considered for this or a future date, please comment against this or subsequent issues.
To modify this process for future maintenance cycles make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation.
</code></pre> </code></pre>
<h4 id="responsibilities-of-team-members">Responsibilities of team members</h4> <h4 id="responsibilities-of-team-members">Responsibilities of team members</h4>
<p>Team members have the following responsibilities.</p> <p>Team members have the following responsibilities.</p>
@ -475,6 +477,8 @@ Checklist:
- [ ] Make a release announcement on the [discussion group](https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework). - [ ] Make a release announcement on the [discussion group](https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework).
- [ ] Make a release announcement on twitter. - [ ] Make a release announcement on twitter.
- [ ] Close the milestone on GitHub. - [ ] Close the milestone on GitHub.
To modify this process for future releases make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation.
</code></pre> </code></pre>
<p>When pushing the release to PyPI ensure that your environment has been installed from our development <code>requirement.txt</code>, so that documentation and PyPI installs are consistently being built against a pinned set of packages.</p> <p>When pushing the release to PyPI ensure that your environment has been installed from our development <code>requirement.txt</code>, so that documentation and PyPI installs are consistently being built against a pinned set of packages.</p>
<hr /> <hr />
@ -488,6 +492,7 @@ Checklist:
<li>Ensure <code>@jamie</code> has back-up access to the <code>django-rest-framework.org</code> domain setup and admin.</li> <li>Ensure <code>@jamie</code> has back-up access to the <code>django-rest-framework.org</code> domain setup and admin.</li>
<li>Document ownership of the <a href="http://restframework.herokuapp.com/">live example</a> API.</li> <li>Document ownership of the <a href="http://restframework.herokuapp.com/">live example</a> API.</li>
<li>Document ownership of the <a href="https://groups.google.com/forum/#!forum/django-rest-framework">mailing list</a> and IRC channel.</li> <li>Document ownership of the <a href="https://groups.google.com/forum/#!forum/django-rest-framework">mailing list</a> and IRC channel.</li>
<li>Document ownership and management of the security mailing list.</li>
</ul> </ul>
</div> </div>

View File

@ -439,6 +439,25 @@
</code></pre> </code></pre>
<hr /> <hr />
<h2 id="30x-series">3.0.x series</h2> <h2 id="30x-series">3.0.x series</h2>
<h3 id="303">3.0.3</h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.3+Release%22">8th January 2015</a>.</p>
<ul>
<li>Fix <code>MinValueValidator</code> on <code>models.DateField</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2369">#2369</a>)</li>
<li>Fix serializer missing context when pagination is used. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2355">#2355</a>)</li>
<li>Namespaced router URLs are now supported by the <code>DefaultRouter</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2351">#2351</a>)</li>
<li><code>required=False</code> allows omission of value for output. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2342">#2342</a>)</li>
<li>Use textarea input for <code>models.TextField</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2340">#2340</a>)</li>
<li>Use custom <code>ListSerializer</code> for pagination if required. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2331">#2331</a>, <a href="https://github.com/tomchristie/django-rest-framework/issues/2327">#2327</a>)</li>
<li>Better behavior with null and '' for blank HTML fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2330">#2330</a>)</li>
<li>Ensure fields in <code>exclude</code> are model fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2319">#2319</a>)</li>
<li>Fix <code>IntegerField</code> and <code>max_length</code> argument incompatibility. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2317">#2317</a>)</li>
<li>Fix the YAML encoder for 3.0 serializers. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2315">#2315</a>, <a href="https://github.com/tomchristie/django-rest-framework/issues/2283">#2283</a>)</li>
<li>Fix the behavior of empty HTML fields. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2311">#2311</a>, <a href="https://github.com/tomchristie/django-rest-framework/issues/1101">#1101</a>)</li>
<li>Fix Metaclass attribute depth ignoring fields attribute. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2287">#2287</a>)</li>
<li>Fix <code>format_suffix_patterns</code> to work with Django's <code>i18n_patterns</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2278">#2278</a>)</li>
<li>Ability to customize router URLs for custom actions, using <code>url_path</code>. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2010">#2010</a>)</li>
<li>Don't install Django REST Framework as egg. (<a href="https://github.com/tomchristie/django-rest-framework/issues/2386">#2386</a>)</li>
</ul>
<h3 id="302">3.0.2</h3> <h3 id="302">3.0.2</h3>
<p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.2+Release%22">17th December 2014</a>.</p> <p><strong>Date</strong>: <a href="https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.2+Release%22">17th December 2014</a>.</p>
<ul> <ul>
@ -983,8 +1002,8 @@
<p>For older release notes, <a href="../../old-release-notes">please see the GitHub repo</a>.</p> <p>For older release notes, <a href="../../old-release-notes">please see the GitHub repo</a>.</p>
<!-- 3.0.1 --> <!-- 3.0.1 -->
<!-- 3.0.2 --> <p><!-- 3.0.2 -->
<!-- 3.0.3 --></p>
</div> </div>
<!--/span--> <!--/span-->

View File

@ -512,7 +512,7 @@ class SnippetSerializer(serializers.Serializer):
</code></pre> </code></pre>
<p>The first part of the serializer class defines the fields that get serialized/deserialized. The <code>create()</code> and <code>update()</code> methods define how fully fledged instances are created or modified when calling <code>serializer.save()</code></p> <p>The first part of the serializer class defines the fields that get serialized/deserialized. The <code>create()</code> and <code>update()</code> methods define how fully fledged instances are created or modified when calling <code>serializer.save()</code></p>
<p>A serializer class is very similar to a Django <code>Form</code> class, and includes similar validation flags on the various fields, such as <code>required</code>, <code>max_length</code> and <code>default</code>.</p> <p>A serializer class is very similar to a Django <code>Form</code> class, and includes similar validation flags on the various fields, such as <code>required</code>, <code>max_length</code> and <code>default</code>.</p>
<p>The field flags can also control how the serializer should be displayed in certain circumstances, such as when rendering to HTML. The <code>style={'type': 'textarea'}</code> flag above is equivelent to using <code>widget=widgets.Textarea</code> on a Django <code>Form</code> class. This is particularly useful for controlling how the browsable API should be displayed, as we'll see later in the tutorial.</p> <p>The field flags can also control how the serializer should be displayed in certain circumstances, such as when rendering to HTML. The <code>{'base_template': 'textarea.html'}</code> flag above is equivelent to using <code>widget=widgets.Textarea</code> on a Django <code>Form</code> class. This is particularly useful for controlling how the browsable API should be displayed, as we'll see later in the tutorial.</p>
<p>We can actually also save ourselves some time by using the <code>ModelSerializer</code> class, as we'll see later, but for now we'll keep our serializer definition explicit.</p> <p>We can actually also save ourselves some time by using the <code>ModelSerializer</code> class, as we'll see later, but for now we'll keep our serializer definition explicit.</p>
<h2 id="working-with-serializers">Working with Serializers</h2> <h2 id="working-with-serializers">Working with Serializers</h2>
<p>Before we go any further we'll familiarize ourselves with using our new Serializer class. Let's drop into the Django shell.</p> <p>Before we go any further we'll familiarize ourselves with using our new Serializer class. Let's drop into the Django shell.</p>
@ -578,7 +578,7 @@ Open the file <code>snippets/serializers.py</code> again, and edit the <code>Sni
SnippetSerializer(): SnippetSerializer():
id = IntegerField(label='ID', read_only=True) id = IntegerField(label='ID', read_only=True)
title = CharField(allow_blank=True, max_length=100, required=False) title = CharField(allow_blank=True, max_length=100, required=False)
code = CharField(style={'type': 'textarea'}) code = CharField(style={'base_template': 'textarea.html'})
linenos = BooleanField(required=False) linenos = BooleanField(required=False)
language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')... language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')...
style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')... style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')...

View File

@ -437,6 +437,7 @@ class SnippetViewSet(viewsets.ModelViewSet):
<p>This time we've used the <code>ModelViewSet</code> class in order to get the complete set of default read and write operations.</p> <p>This time we've used the <code>ModelViewSet</code> class in order to get the complete set of default read and write operations.</p>
<p>Notice that we've also used the <code>@detail_route</code> decorator to create a custom action, named <code>highlight</code>. This decorator can be used to add any custom endpoints that don't fit into the standard <code>create</code>/<code>update</code>/<code>delete</code> style.</p> <p>Notice that we've also used the <code>@detail_route</code> decorator to create a custom action, named <code>highlight</code>. This decorator can be used to add any custom endpoints that don't fit into the standard <code>create</code>/<code>update</code>/<code>delete</code> style.</p>
<p>Custom actions which use the <code>@detail_route</code> decorator will respond to <code>GET</code> requests. We can use the <code>methods</code> argument if we wanted an action that responded to <code>POST</code> requests.</p> <p>Custom actions which use the <code>@detail_route</code> decorator will respond to <code>GET</code> requests. We can use the <code>methods</code> argument if we wanted an action that responded to <code>POST</code> requests.</p>
<p>The URLs for custom actions by default depend on the method name itself. If you want to change the way url should be constructed, you can include url_path as a decorator keyword argument.</p>
<h2 id="binding-viewsets-to-urls-explicitly">Binding ViewSets to URLs explicitly</h2> <h2 id="binding-viewsets-to-urls-explicitly">Binding ViewSets to URLs explicitly</h2>
<p>The handler methods only get bound to the actions when we define the URLConf. <p>The handler methods only get bound to the actions when we define the URLConf.
To see what's going on under the hood let's first explicitly create a set of views from our ViewSets.</p> To see what's going on under the hood let's first explicitly create a set of views from our ViewSets.</p>