21👍
HttpRequest.META
, more specifically HttpRequest.META.get('HTTP_ACCEPT')
— and not as mentioned earlierHttpRequest.META.get('CONTENT_TYPE')
21👍
‘Content-Type’ header indicates media type send in the HTTP request. This is used for requests that have a content (POST, PUT).
‘Content-Type’ should not be used to indicate preferred response format, ‘Accept’ header serves this purpose. To access it in Django use: HttpRequest.META.get('HTTP_ACCEPT')
- [Django]-How to use regex in django query
- [Django]-Django bytesIO to base64 String & return as JSON
- [Django]-Django: Populate user ID when saving a model
5👍
As said in other answers, this information is located in the Accept
request header. Available in the request as HttpRequest.META['HTTP_ACCEPT']
.
However there is no only one requested content type, and this header often is a list of accepted/preferred content types. This list might be a bit annoying to exploit properly. Here is a function that does the job:
import re
def get_accepted_content_types(request):
def qualify(x):
parts = x.split(';', 1)
if len(parts) == 2:
match = re.match(r'(^|;)q=(0(\.\d{,3})?|1(\.0{,3})?)(;|$)',
parts[1])
if match:
return parts[0], float(match.group(2))
return parts[0], 1
raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
qualified_content_types = map(qualify, raw_content_types)
return (x[0] for x in sorted(qualified_content_types,
key=lambda x: x[1], reverse=True))
For instance, if request.META['HTTP_ACCEPT']
is equal to "text/html;q=0.9,application/xhtml+xml,application/xml;q=0.8,*/*;q=0.7"
. This will return: ['application/xhtml+xml', 'text/html', 'application/xml', '*/*']
(not actually, since it returns a generator).
Then you can iterate over the resulting list to select the first content type you know how to respond properly.
Note that this function should work for most cases but do not handle cases such as q=0
which means “Not acceptable”.
Sources: HTTP Accept header specification and Quality Values specification
- [Django]-How can I chain Django's "in" and "iexact" queryset field lookups?
- [Django]-Clean way to use postgresql window functions in django ORM?
- [Django]-Django humanize outside of template?
3👍
in django 1.10, you can now use, request.content_type
, as mentioned here in their doc
- [Django]-How can i pass data to django layouts (like 'base.html') without having to provide it through every view?
- [Django]-How to access my 127.0.0.1:8000 from Android tablet
- [Django]-Access Python Development Server from External IP
1👍
As of Django 3.1, there is the HttpRequest.accepts(mime_type)
method which determines whether a particular content type is acceptable by the client.
There is a useful example linked by that documentation which shows how a CreateView
could support JSON responses:
from django.http import JsonResponse
from django.views.generic.edit import CreateView
from myapp.models import Author
class JsonableResponseMixin:
"""
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.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.accepts("text/html"):
return response
else:
data = {
"pk": self.object.pk,
}
return JsonResponse(data)
class AuthorCreateView(JsonableResponseMixin, CreateView):
model = Author
fields = ["name"]
- [Django]-Creating a REST API for a Django application
- [Django]-Chaining multiple filter() in Django, is this a bug?
- [Django]-Django: how to do get_or_create() in a threadsafe way?