Skip to content
This repository was archived by the owner on May 2, 2023. It is now read-only.

Format results server side

Maigret Aurélien edited this page Jun 27, 2017 · 4 revisions

Standard response

To make the formatting of your result easier, you can define a generic object for your API class. It will be used automatically to format the results of your model. This object (called format_object) contains the list of fields that you want to return. You could specify the model's field to use in a sub-object, with the key field. If the key do not exist, the key of the sub-object is used as a field instead. Example:

from rest_api.API import API
from rest_api.errors import ResponseNotFound
from example.models import Project

class ProjectAPI(API):
    format_object = {
        "id": {},
        "name": {},
        "owner": {"field": "owner__email"}
    }

    # GET /api/1.0/project/<id>
    def method_get_detail(self, session, request, _id, **kwargs):
        try:
            project = Project.objects.get(pk=_id)
        except:
            raise ResponseNotFound(details=["Project not found"])
        return self.response(self.format(project))
$> curl -X GET http://127.0.0.1:8000/api/1.0/project/1
{
    "id": 1,
    "name": "Skies",
    "owner": "[email protected]"
}

This method also works for the results of type list. Moreover, you can specify whether you don't want a specific field in this type (with the parameter list to False in the sub-object). It will be seen only with the type detail. Example:

from rest_api.API import API
from rest_api.errors import ResponseNotFound
from example.models import Project

class ProjectAPI(API):
    format_object = {
        "id": {},
        "name": {},
        "owner": {"field": "owner__email", "list": False}
    }

    # GET /api/1.0/project/<id>
    def method_get_detail(self, session, request, _id, **kwargs):
        try:
            project = Project.objects.get(pk=_id)
        except:
            raise ResponseNotFound(details=["Project not found"])
        return self.response(self.format(project))
$> curl -X GET http://127.0.0.1:8000/api/1.0/project
{
    "count_results": 2,
    "current_page": 1,
    "format": {
        "id": "id",
        "name": "name"
    },
    "limit": 25,
    "number_pages": 1,
    "results": [
        {
            "id": 1,
            "name": "Skies"
        },
        {
            "id": 2,
            "name": "ComeOn"
    ],
    "total_results": 2
}
$> curl -X GET http://127.0.0.1:8000/api/1.0/project/1
{
    "id": 1,
    "name": "Skies",
    "owner": "[email protected]"
}

The type list is automatically set when you call the method pagination (LINK TO Pagination). If you don't call this method, you can force his type:

self.is_list = True
self.format(item)

By default, the method format choice the format object self.format_object. But you can specify an other format (for your custom route for example):

self.format(item, _format=self.format_object_contributors)

You could also find an example in project.py.

Sub-objects

The sub-objects could be more complex. You can for example create really a sub-object in the result, in the key object:

format_object = {
    "id": {},
    "name": {},
    "owner": {
        "object": {
            "id": {"field": "owner__id"},
            "email": {"field": "owner__email"}
        }
    }
}
$> curl -X GET http://127.0.0.1:8000/api/1.0/project/1
{
    "id": 1,
    "name": "Skies",
    "owner": {
        "id": 2,
        "email": "[email protected]"
    }
}

Or it may happen that one of the fields is a ManyToManyField (an array of sub-results). In this case, you don't have to specify the field name in the key field, but in the key object_list:

format_object = {
    "id": {},
    "name": {},
    "owner": {
        "object": {
            "id": {"field": "owner__id"},
            "email": {"field": "owner__email"}
        }
    },
    "contributors": {
        "list": False,
        "object_list": "contributors",
        "object_list_order": "id",
        "object": {
            "id": {"field": "id"},
            "email": {"field": "email"}
        }
    }
}
$> curl -X GET http://127.0.0.1:8000/api/1.0/project/2
{
    "contributors": [
        {
            "email": "[email protected]",
            "id": 2
        },
        {
            "email": "[email protected]",
            "id": 3
        }
    ],
    "id": 2,
    "name": "ComeOn",
    "owner": {
        "email": "[email protected]",
        "id": 1
    }
}
Clone this wiki locally