1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #35631 -- Added HttpRequest.get_preferred_type().

This commit is contained in:
Jake Howard
2024-07-26 12:34:42 +01:00
committed by Sarah Boyce
parent 826ef00668
commit e161bd4657
5 changed files with 247 additions and 26 deletions

View File

@@ -273,3 +273,56 @@ works with an API-based workflow as well as 'normal' form POSTs::
class AuthorCreateView(JsonableResponseMixin, CreateView):
model = Author
fields = ["name"]
The above example assumes that if the client supports ``text/html``, that they
would prefer it. However, this may not always be true. When requesting a
``.css`` file, many browsers will send the header
``Accept: text/css,*/*;q=0.1``, indicating that they would prefer CSS, but
anything else is fine. This means ``request.accepts("text/html") will be
``True``.
To determine the correct format, taking into consideration the client's
preference, use :func:`django.http.HttpRequest.get_preferred_type`::
class JsonableResponseMixin:
"""
Mixin to add JSON support to a form.
Must be used with an object-based FormView (e.g. CreateView).
"""
accepted_media_types = ["text/html", "application/json"]
def dispatch(self, request, *args, **kwargs):
if request.get_preferred_type(self.accepted_media_types) is None:
# No format in common.
return HttpResponse(
status_code=406, headers={"Accept": ",".join(self.accepted_media_types)}
)
return super().dispatch(request, *args, **kwargs)
def form_invalid(self, form):
response = super().form_invalid(form)
accepted_type = request.get_preferred_type(self.accepted_media_types)
if accepted_type == "text/html":
return response
elif accepted_type == "application/json":
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)
accepted_type = request.get_preferred_type(self.accepted_media_types)
if accepted_type == "text/html":
return response
elif accepted_type == "application/json":
data = {
"pk": self.object.pk,
}
return JsonResponse(data)
.. versionchanged:: 5.2
The :meth:`.HttpRequest.get_preferred_type` method was added.