Reputation: 123
How can you conditionally return a JSON or HTML response from Django django-rest-framework's view?
djangorestframework
== 2.3.10
My settings.py
:
REST_FRAMEWORK = {
'PAGINATE_BY': 10,
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.TemplateHTMLRenderer',
'rest_framework.renderers.JSONRenderer',
)
}
url.py
, I added this as the last line:urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html'])
def myview(request, id, format='json'):
if format == 'json' or format is None:
return Response(my_dict, status=status.HTTP_200_OK)
else:
return Response(my_dict, template_name='myhtml.html')
Everything works OK, if I explicitly use .html
or .json
format_prefix
in the url request. But it gives me the following error if I don't specify any format.
ImproperlyConfigured at /objects/29
Returned a template response with notemplate_name
attribute set on either the view or response
Request Method: GET
Request URL: localhost:8000/objects/29
Django Version: 1.7
Exception Type: ImproperlyConfigured
Exception Value: Returned a template response with notemplate_name
attribute set on either the view or response
Exception Location: D:\WORKSPACE\user...\lib\site-
I also tried:
urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html', 'None'])
But it doesn't seem to work either.
Could someone please help? Thanks!
Upvotes: 7
Views: 8507
Reputation: 380
After research this worked for me Below django view acts as template renderer and json renderer
views.py
from rest_framework.renderers import JSONRenderer, TemplateHTMLRenderer
from rest_framework.decorators import api_view, renderer_classes
from django.http.response import JsonResponse
from django.shortcuts import render
@api_view(['GET','POST'])
@renderer_classes([JSONRenderer,TemplateHTMLRenderer])
def myview(request, id, format='json'):
if format == 'json' or format is None:
return JsonResponse(my_dict, status=status.HTTP_200_OK)
else:
return render(request,'template_name.html',{"context":my_dict})
settings.py
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.TemplateHTMLRenderer',
),
}
The above view will act like both Json renderer and Template renderer. Based on the condition you can see the behavior.
Upvotes: 1
Reputation: 3543
This worked for me:
class MyView(ListAPIView):
renderer_classes = (JSONRenderer, TemplateHTMLRenderer,)
def get(self, request, *args, **kwargs):
data = SomerSerializer([]).data
if request.accepted_renderer.format == 'html':
return Response(data, template_name='blah.html')
return Response(data)
FYI I've gotten this error before, but it wasn't because it was configured properly - it was because some unrelated code right before it errored out - so look for anything else that might be failing. Also note that your 'else' is redundant.
Upvotes: 6