I have a working Django 1.8 site, and I want to add a RESTful API using django-rest-framework. I would like to support rendering to CSV and JSON formats, and am puzzling over how to do this.
In api/urls.py
I have this:
from django.conf.urls import url, include
from rest_framework import routers
from rest_framework.urlpatterns import format_suffix_patterns
import views
router = routers.DefaultRouter()
urlpatterns = [
url(r'^organisation/$', views.organisation),
]
urlpatterns = format_suffix_patterns(urlpatterns,
allowed=['json', 'csv'])
And I have this in api/views.py
:
class JSONResponse(HttpResponse):
"""
An HttpResponse that renders its content into JSON.
"""
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
@api_view(['GET'])
def organisation(request, format=None):
code = request.query_params.get('code', None)
print 'format', format
organisation = Organisation.objects.get(code=code)
serializer = OrgSerializer(organisation)
data = serializer.data
return JSONResponse(data)
But if I go to api/1.0/organisation.csv?code=123
, I still see:
format json
in the console.
What am I doing wrong? And how should I return CSV once I have managed to capture the format? (I suspect I'm probably doing the wrong thing by writing my own JSONResponse
, already.)
This is an old post, but I've seen the accepted answer sets the
CSVRenderer
as one of the defaults, which is not usually wanted.I would implement the view this way:
Of course, having the
django-rest-framework-csv
installed andOrgSerializer
defined somewhere.Then you can just set
'rest_framework.renderers.JSONRenderer'
as your default renderer in settings and the rest framework will automatically return csv content if you request it on theHTTP_ACCEPT
header - just for this view.If you just need to download CSV (without Model serialization etc)
Got it. The trick is to install djangorestframework-csv, then add the following in settings:
And then scrap the
JSONResponse
function inviews.py
and just doreturn Response(serializer.data)
instead. Very easy in the end.