summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2019-11-17 13:24:10 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-01-24 14:24:59 +0100
commitd66d72f95655312c413d916add61a62928639514 (patch)
tree575b6ab25fe1ff4e60ad4e527c8fc72f973dfb18 /docs
parentcf493e5c819f5ee49b96954f026bec722e19d9c3 (diff)
Refs #30997 -- Added HttpRequest.accepts().
Diffstat (limited to 'docs')
-rw-r--r--docs/ref/request-response.txt23
-rw-r--r--docs/releases/3.1.txt3
-rw-r--r--docs/topics/class-based-views/generic-editing.txt26
3 files changed, 40 insertions, 12 deletions
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index 370993444b..2f9e78e358 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -406,6 +406,29 @@ Methods
Returns ``True`` if the request is secure; that is, if it was made with
HTTPS.
+.. method:: HttpRequest.accepts(mime_type)
+
+ .. versionadded:: 3.1
+
+ Returns ``True`` if the request ``Accept`` header matches the ``mime_type``
+ argument::
+
+ >>> request.accepts('text/html')
+ True
+
+ Most browsers send ``Accept: */*`` by default, so this would return
+ ``True`` for all content types. Setting an explicit ``Accept`` header in
+ API requests can be useful for returning a different content type for those
+ consumers only. See :ref:`content-negotiation-example` of using
+ ``accepts()`` to return different content to API consumers.
+
+ If a response varies depending on the content of the ``Accept`` header and
+ you are using some form of caching like Django's :mod:`cache middleware
+ <django.middleware.cache>`, you should decorate the view with
+ :func:`vary_on_headers('Accept')
+ <django.views.decorators.vary.vary_on_headers>` so that the responses are
+ properly cached.
+
.. method:: HttpRequest.is_ajax()
Returns ``True`` if the request was made via an ``XMLHttpRequest``, by
diff --git a/docs/releases/3.1.txt b/docs/releases/3.1.txt
index 709c3917bc..3c88ecadd7 100644
--- a/docs/releases/3.1.txt
+++ b/docs/releases/3.1.txt
@@ -282,6 +282,9 @@ Requests and Responses
now allow using ``samesite='None'`` (string) to explicitly state that the
cookie is sent with all same-site and cross-site requests.
+* The new :meth:`.HttpRequest.accepts` method returns whether the request
+ accepts the given MIME type according to the ``Accept`` HTTP header.
+
Serialization
~~~~~~~~~~~~~
diff --git a/docs/topics/class-based-views/generic-editing.txt b/docs/topics/class-based-views/generic-editing.txt
index c1e73fc2fb..7c61592142 100644
--- a/docs/topics/class-based-views/generic-editing.txt
+++ b/docs/topics/class-based-views/generic-editing.txt
@@ -222,41 +222,43 @@ to edit, and override
aren't logged in from accessing the form. If you omit that, you'll need to
handle unauthorized users in :meth:`~.ModelFormMixin.form_valid()`.
-AJAX example
-============
+.. _content-negotiation-example:
+
+Content negotiation example
+===========================
Here is an example showing how you might go about implementing a form that
-works for AJAX requests as well as 'normal' form POSTs::
+works with an API-based workflow as well as 'normal' form POSTs::
from django.http import JsonResponse
from django.views.generic.edit import CreateView
from myapp.models import Author
- class AjaxableResponseMixin:
+ class JsonableResponseMixin:
"""
- Mixin to add AJAX support to a form.
+ Mixin to add JSON support to a form.
Must be used with an object-based FormView (e.g. CreateView)
"""
def form_invalid(self, form):
response = super().form_invalid(form)
- if self.request.is_ajax():
- return JsonResponse(form.errors, status=400)
- else:
+ if self.request.accepts('text/html'):
return response
+ else:
+ return JsonResponse(form.errors, status=400)
def form_valid(self, form):
# We make sure to call the parent's form_valid() method because
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
response = super().form_valid(form)
- if self.request.is_ajax():
+ if self.request.accepts('text/html'):
+ return response
+ else:
data = {
'pk': self.object.pk,
}
return JsonResponse(data)
- else:
- return response
- class AuthorCreate(AjaxableResponseMixin, CreateView):
+ class AuthorCreate(JsonableResponseMixin, CreateView):
model = Author
fields = ['name']