Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate JSON-API data attribute vs results attribute in Django Rest Framework JSON API?

I have a django 1.9.2 project using Django Rest Framework JSON API:

https://github.com/django-json-api/django-rest-framework-json-api:

My viewset looks like this:

class QuestionViewSet(viewsets.ReadOnlyModelViewSet):
    """
    API endpoint that allows questions and answers to be read.
    """
    resource_name = 'questions'
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer
    renderers = renderers.JSONRenderer
    parsers = parsers.JSONParser

Typical response looks like this:

{"links": {"first": "http://testserver/api/v1/coaches?page=1", "last": "http://testserver/api/v1/coaches?page=1", "next": null, "prev": null}, "results": [{"id": 1, "created": "2016-02-11T02:41:22.569000Z", "updated": null, "deleted": null, "uuid": "0473c709-994f-465b-989e-407c623f365f", "user": {"type": "User", "id": "2"}}, {"id": 2, "created": "2016-02-11T02:41:46.853000Z", "updated": null, "deleted": null, "uuid": "36e19c0e-bda6-4bd7-bc73-374a6fc509d6", "user": {"type": "User", "id": "3"}}, {"id": 3, "created": "2016-02-11T02:42:05.419000Z", "updated": null, "deleted": null, "uuid": "d0798ff4-3be2-4cf3-81ac-edf8049eb075", "user": {"type": "User", "id": "4"}}], "meta": {"pagination": {"page": 1, "pages": 1, "count": 3}}}

I want the output to have a data attribute as opposed to the results attribute. How can I tell DRF JSON API to output the style described here:

http://jsonapi.org/format/

like image 922
David Watson Avatar asked Feb 12 '16 08:02

David Watson


People also ask

What is JSONRenderer?

The JSONRenderer exposes a number of methods that you may override if you need highly custom rendering control. Render a JSON response per the JSON:API spec: { "data": [ { "type": "companies", "id": "1", "attributes": { "name": "Mozilla", "slug": "mozilla", "date-created": "2014-03-13 16:33:37" } } ] }

What is the difference between Django and REST API?

Django is the web development framework in python whereas the Django Rest Framework is the library used in Django to build Rest APIs. Django Rest Framework is especially designed to make the CRUD operations easier to design in Django. Django Rest Framework makes it easy to use your Django Server as an REST API.


1 Answers

The problem in my case was that I had a viewset derived class in the view like this:

class QuestionViewSet(viewsets.ReadOnlyModelViewSet):
    """
    API endpoint that allows questions and answers to be read.
    """
    resource_name = 'questions'
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer
    renderers = renderers.JSONRenderer
    parsers = parsers.JSONParser

This is wrong. The renderers and parsers attributes are actually renderer_classes and parser_classes, respectively. Moreover, the rvalues of those attributes are tuples, not singletons. Thus:

class QuestionViewSet(viewsets.ReadOnlyModelViewSet):
    """
    API endpoint that allows questions and answers to be read.
    """
    resource_name = 'questions'
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer
    renderer_classes = (renderers.JSONRenderer,)
    parser_classes = (parsers.JSONParser,)

After this change, the JSON API response is largely correct:

{"data":{"type":"questions","id":"1","attributes":{"created":"2016-02-10T04:28:50.742000Z","updated":null,"deleted":null,"uuid":"eddfc27d-2677-49e5-bd37-92fecea340bd","text":"Are you dizzy?"},"relationships":{"answers":{"data":[{"type":"Answer","id":"1"},{"type":"Answer","id":"2"},{"type":"Answer","id":"3"}]},"members":{"data":[{"type":"Member","id":"1"},{"type":"Member","id":"2"},{"type":"Member","id":"3"},{"type":"Member","id":"4"}],"meta":{"count":4}}}}}
like image 66
David Watson Avatar answered Oct 19 '22 22:10

David Watson