Skip to content

Commit c058ab3

Browse files
committed
Merge pull request #2 from tomchristie/master
Update to latest
2 parents bf8e71c + 43a5f81 commit c058ab3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+977
-224
lines changed

docs/api-guide/authentication.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ To use the `TokenAuthentication` scheme, include `rest_framework.authtoken` in y
121121
'rest_framework.authtoken'
122122
)
123123

124-
Make sure to run `manage.py syncdb` after changing your settings.
124+
Make sure to run `manage.py syncdb` after changing your settings. The `authtoken` database tables are managed by south (see [Schema migrations](#schema-migrations) below).
125125

126126
You'll also need to create tokens for your users.
127127

@@ -184,9 +184,11 @@ The `obtain_auth_token` view will return a JSON response when valid `username` a
184184

185185
Note that the default `obtain_auth_token` view explicitly uses JSON requests and responses, rather than using default renderer and parser classes in your settings. If you need a customized version of the `obtain_auth_token` view, you can do so by overriding the `ObtainAuthToken` view class, and using that in your url conf instead.
186186

187-
#### Custom user models
187+
#### Schema migrations
188188

189-
The `rest_framework.authtoken` app includes a south migration that will create the authtoken table. If you're using a [custom user model][custom-user-model] you'll need to make sure that any initial migration that creates the user table runs before the authtoken table is created.
189+
The `rest_framework.authtoken` app includes a south migration that will create the authtoken table.
190+
191+
If you're using a [custom user model][custom-user-model] you'll need to make sure that any initial migration that creates the user table runs before the authtoken table is created.
190192

191193
You can do so by inserting a `needed_by` attribute in your user migration:
192194

@@ -201,6 +203,12 @@ You can do so by inserting a `needed_by` attribute in your user migration:
201203

202204
For more details, see the [south documentation on dependencies][south-dependencies].
203205

206+
Also note that if you're using a `post_save` signal to create tokens, then the first time you create the database tables, you'll need to ensure any migrations are run prior to creating any superusers. For example:
207+
208+
python manage.py syncdb --noinput # Won't create a superuser just yet, due to `--noinput`.
209+
python manage.py migrate
210+
python manage.py createsuperuser
211+
204212
## SessionAuthentication
205213

206214
This authentication scheme uses Django's default session backend for authentication. Session authentication is appropriate for AJAX clients that are running in the same session context as your website.

docs/api-guide/content-negotiation.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ This is a valid approach as the HTTP spec deliberately underspecifies how a serv
4343

4444
It's unlikely that you'll want to provide a custom content negotiation scheme for REST framework, but you can do so if needed. To implement a custom content negotiation scheme override `BaseContentNegotiation`.
4545

46-
REST framework's content negotiation classes handle selection of both the appropriate parser for the request, and the appropriate renderer for the response, so you should implement both the `.select_parser(request, parsers)` and `.select_renderer(request, renderers, format_suffix)` methods.
46+
REST framework's content negotiation classes handle selection of both the appropriate parser for the request, and the appropriate renderer for the response, so you should implement both the `.select_parser(request, parsers)` and `.select_renderer(request, renderers, format_suffix)` methods.
47+
48+
The `select_parser()` method should return one of the parser instances from the list of available parsers, or `None` if none of the parsers can handle the incoming request.
49+
50+
The `select_renderer()` method should return a two-tuple of (renderer instance, media type), or raise a `NotAcceptable` exception.
4751

4852
## Example
4953

@@ -61,6 +65,27 @@ request when selecting the appropriate parser or renderer.
6165
"""
6266
Select the first renderer in the `.renderer_classes` list.
6367
"""
64-
return renderers[0]
68+
return (renderers[0], renderers[0].media_type)
69+
70+
## Setting the content negotiation
71+
72+
The default content negotiation class may be set globally, using the `DEFAULT_CONTENT_NEGOTIATION_CLASS` setting. For example, the following settings would use our example `IgnoreClientContentNegotiation` class.
73+
74+
REST_FRAMEWORK = {
75+
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'myapp.negotiation.IgnoreClientContentNegotiation',
76+
}
77+
78+
You can also set the content negotiation used for an individual view, or viewset, using the `APIView` class based views.
79+
80+
class NoNegotiationView(APIView):
81+
"""
82+
An example view that does not perform content negotiation.
83+
"""
84+
content_negotiation_class = IgnoreClientContentNegotiation
85+
86+
def get(self, request, format=None):
87+
return Response({
88+
'accepted media type': request.accepted_renderer.media_type
89+
})
6590

6691
[accept-header]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

docs/api-guide/renderers.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,24 @@ Renders data into HTML for the Browsable API. This renderer will determine whic
217217

218218
**.charset**: `utf-8`
219219

220+
#### Customizing BrowsableAPIRenderer
221+
222+
By default the response content will be rendered with the highest priority renderer apart from `BrowseableAPIRenderer`. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the `get_default_renderer()` method. For example:
223+
224+
class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
225+
def get_default_renderer(self, view):
226+
return JSONRenderer()
227+
228+
## MultiPartRenderer
229+
230+
This renderer is used for rendering HTML multipart form data. **It is not suitable as a response renderer**, but is instead used for creating test requests, using REST framework's [test client and test request factory][testing].
231+
232+
**.media_type**: `multipart/form-data; boundary=BoUnDaRyStRiNg`
233+
234+
**.format**: `'.multipart'`
235+
236+
**.charset**: `utf-8`
237+
220238
---
221239

222240
# Custom renderers
@@ -373,6 +391,7 @@ Comma-separated values are a plain-text tabular data format, that can be easily
373391
[rfc4627]: http://www.ietf.org/rfc/rfc4627.txt
374392
[cors]: http://www.w3.org/TR/cors/
375393
[cors-docs]: ../topics/ajax-csrf-cors.md
394+
[testing]: testing.md
376395
[HATEOAS]: http://timelessrepo.com/haters-gonna-hateoas
377396
[quote]: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
378397
[application/vnd.github+json]: http://developer.github.com/v3/media/

docs/api-guide/serializers.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,12 @@ By default, all the model fields on the class will be mapped to corresponding se
308308

309309
Any relationships such as foreign keys on the model will be mapped to `PrimaryKeyRelatedField`. Other models fields will be mapped to a corresponding serializer field.
310310

311+
---
312+
313+
**Note**: When validation is applied to a `ModelSerializer`, both the serializer fields, and their corresponding model fields must correctly validate. If you have optional fields on your model, make sure to correctly set `blank=True` on the model field, as well as setting `required=False` on the serializer field.
314+
315+
---
316+
311317
## Specifying which fields should be included
312318

313319
If you only want a subset of the default fields to be used in a model serializer, you can do so using `fields` or `exclude` options, just as you would with a `ModelForm`.
@@ -423,6 +429,49 @@ You can create customized subclasses of `ModelSerializer` or `HyperlinkedModelSe
423429

424430
Doing so should be considered advanced usage, and will only be needed if you have some particular serializer requirements that you often need to repeat.
425431

432+
## Dynamically modifiying fields
433+
434+
Once a serializer has been initialized, the dictionary of fields that are set on the serializer may be accessed using the `.fields` attribute. Accessing and modifying this attribute allows you to dynamically modify the serializer.
435+
436+
Modifying the `fields` argument directly allows you to do interesting things such as changing the arguments on serializer fields at runtime, rather than at the point of declaring the serializer.
437+
438+
### Example
439+
440+
For example, if you wanted to be able to set which fields should be used by a serializer at the point of initializing it, you could create a serializer class like so:
441+
442+
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
443+
"""
444+
A ModelSerializer that takes an additional `fields` argument that
445+
controls which fields should be displayed.
446+
"""
447+
448+
def __init__(self, *args, **kwargs):
449+
# Don't pass the 'fields' arg up to the superclass
450+
fields = kwargs.pop('fields', None)
451+
452+
# Instatiate the superclass normally
453+
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
454+
455+
if fields:
456+
# Drop any fields that are not specified in the `fields` argument.
457+
allowed = set(fields)
458+
existing = set(self.fields.keys())
459+
for field_name in existing - allowed:
460+
self.fields.pop(field_name)
461+
462+
This would then allow you to do the following:
463+
464+
>>> class UserSerializer(DynamicFieldsModelSerializer):
465+
>>> class Meta:
466+
>>> model = User
467+
>>> fields = ('id', 'username', 'email')
468+
>>>
469+
>>> print UserSerializer(user)
470+
{'id': 2, 'username': 'jonwatts', 'email': '[email protected]'}
471+
>>>
472+
>>> print UserSerializer(user, fields=('id', 'email'))
473+
{'id': 2, 'email': '[email protected]'}
474+
426475
## Customising the default fields
427476

428477
The `field_mapping` attribute is a dictionary that maps model classes to serializer classes. Overriding the attribute will let you set a different set of default serializer classes.
@@ -457,7 +506,7 @@ Note that the `model_field` argument will be `None` for reverse relationships.
457506

458507
Returns the field instance that should be used for non-relational, non-pk fields.
459508

460-
## Example
509+
### Example
461510

462511
The following custom model serializer could be used as a base class for model serializers that should always exclude the pk by default.
463512

docs/api-guide/settings.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,33 @@ Default: `None`
149149

150150
---
151151

152+
## Test settings
153+
154+
*The following settings control the behavior of APIRequestFactory and APIClient*
155+
156+
#### TEST_REQUEST_DEFAULT_FORMAT
157+
158+
The default format that should be used when making test requests.
159+
160+
This should match up with the format of one of the renderer classes in the `TEST_REQUEST_RENDERER_CLASSES` setting.
161+
162+
Default: `'multipart'`
163+
164+
#### TEST_REQUEST_RENDERER_CLASSES
165+
166+
The renderer classes that are supported when building test requests.
167+
168+
The format of any of these renderer classes may be used when contructing a test request, for example: `client.post('/users', {'username': 'jamie'}, format='json')`
169+
170+
Default:
171+
172+
(
173+
'rest_framework.renderers.MultiPartRenderer',
174+
'rest_framework.renderers.JSONRenderer'
175+
)
176+
177+
---
178+
152179
## Browser overrides
153180

154181
*The following settings provide URL or form-based overrides of the default browser behavior.*

0 commit comments

Comments
 (0)