diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index c69953607..ae21c66eb 100644 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -50,9 +50,9 @@ You can also set the authentication policy on a per-view basis, using the `APIVi Or, if you're using the `@api_view` decorator with function based views. - @api_view('GET'), - @authentication_classes(SessionAuthentication, UserBasicAuthentication) - @permissions_classes(IsAuthenticated) + @api_view(('GET',)), + @authentication_classes((SessionAuthentication, UserBasicAuthentication)) + @permissions_classes((IsAuthenticated,)) def example_view(request, format=None): content = { 'user': unicode(request.user), # `django.contrib.auth.User` instance. diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index f27eb3601..2b1f423dd 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -60,6 +60,8 @@ For example if your API serves JSON responses and the HTML browseable API, you m If your API includes views that can serve both regular webpages and API responses depending on the request, then you might consider making `TemplateHTMLRenderer` your default renderer, in order to play nicely with older browsers that send [broken accept headers][browser-accept-headers]. +--- + # API Reference ## JSONRenderer @@ -119,6 +121,8 @@ If you're building websites that use `HTMLTemplateRenderer` along with other ren To implement a custom renderer, you should override `BaseRenderer`, set the `.media_type` and `.format` properties, and implement the `.render(self, data, media_type)` method. +--- + # Advanced renderer usage You can do some pretty flexible things using REST framework's renderers. Some examples... @@ -128,6 +132,8 @@ You can do some pretty flexible things using REST framework's renderers. Some e * Specify multiple types of HTML representation for API clients to use. * Underspecify a renderer's media type, such as using `media_type = 'image/*'`, and use the `Accept` header to vary the encoding of the response. +## Varying behaviour by media type + In some cases you might want your view to use different serialization styles depending on the accepted media type. If you need to do this you can access `request.accepted_renderer` to determine the negotiated renderer that will be used for the response. For example: diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 901d23d12..44f677cc2 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -23,7 +23,7 @@ class BaseView(views.APIView): """ return { 'request': self.request, - 'format': self.format, + 'format': self.format_kwarg, 'view': self } diff --git a/rest_framework/views.py b/rest_framework/views.py index 0359c2259..166bf0b16 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -162,13 +162,19 @@ class APIView(View): """ return [throttle(self) for throttle in self.throttle_classes] + def get_content_negotiator(self): + """ + Instantiate and return the content negotiation class to use. + """ + return self.content_negotiation_class() + def perform_content_negotiation(self, request, force=False): """ Determine which renderer and media type to use render the response. """ renderers = self.get_renderers() - conneg = self.content_negotiation_class() - return conneg.negotiate(request, renderers, self.format, force) + conneg = self.get_content_negotiator() + return conneg.negotiate(request, renderers, self.format_kwarg, force) def has_permission(self, request, obj=None): """ @@ -198,7 +204,7 @@ class APIView(View): """ Runs anything that needs to occur prior to calling the method handlers. """ - self.format = self.get_format_suffix(**kwargs) + self.format_kwarg = self.get_format_suffix(**kwargs) if not self.has_permission(request): self.permission_denied(request)