将根元素添加到json响应(django-rest-framework) [英] Adding root element to json response (django-rest-framework)

查看:138
本文介绍了将根元素添加到json响应(django-rest-framework)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图确定使用django和django-rest-framework为所有json响应添加根元素的最佳方法。

I am trying to determine the best way to add a root element to all json responses using django and django-rest-framework.

我想添加一个自定义渲染器是完成我想要实现的最好的方法,这是迄今为止我已经提出的:

I think adding a custom renderer is the best way to accomplish what I want to achieve and this is what I have come up with so far:

from rest_framework.renderers import JSONRenderer

class CustomJSONRenderer(JSONRenderer):
#override the render method
def render(self, data, accepted_media_type=None, renderer_context=None):
    #call super, as we really just want to mess with the data returned
    json_str = super(CustomJSONRenderer, self).render(data, accepted_media_type, renderer_context)
    root_element = 'contact'

    #wrap the json string in the desired root element
    ret = '{%s: %s}' % (root_element, json_str) 

    return ret

现在,棘手的部分是动态设置 root_element 查看 render()正在被调用。

The tricky part now is dynamically setting the root_element based on the view that render() is being called from.

任何指针/建议将不胜感激,

Any pointers/advice would be greatly appreciated,

Cheers

推荐答案

对于后代,下面是最终的解决方案。它已经从原来略有增长,因为它现在也重新格式化了分页结果。

For posterity, below is the final solution. It has grown slightly from the original as it now reformats paginated results as well.

此外,我还应该指定之前,JSON根元素的原因是用于与Ember前端解决方案集成。

Also I should have specified before, that the reason for the JSON root element is for integration with an Ember front end solution.

serializer:

serializer:

from rest_framework.serializers import ModelSerializer
from api.models import Contact

class ContactSerializer(ModelSerializer):
    class Meta:
        model = Contact
        #define the resource we wish to use for the root element of the response
        resource_name = 'contact' 
        fields = ('id', 'first_name', 'last_name', 'phone_number', 'company')

renderer:

from rest_framework.renderers import JSONRenderer

class CustomJSONRenderer(JSONRenderer):
"""
    Override the render method of the django rest framework JSONRenderer to allow the following:
    * adding a resource_name root element to all GET requests formatted with JSON
    * reformatting paginated results to the following structure {meta: {}, resource_name: [{},{}]}

    NB: This solution requires a custom pagination serializer and an attribute of 'resource_name'
        defined in the serializer
"""
def render(self, data, accepted_media_type=None, renderer_context=None):
    response_data = {}

    #determine the resource name for this request - default to objects if not defined
    resource = getattr(renderer_context.get('view').get_serializer().Meta, 'resource_name', 'objects')

    #check if the results have been paginated
    if data.get('paginated_results'):
        #add the resource key and copy the results
        response_data['meta'] = data.get('meta')
        response_data[resource] = data.get('paginated_results')
    else:
        response_data[resource] = data

    #call super to render the response
    response = super(CustomJSONRenderer, self).render(response_data, accepted_media_type, renderer_context)

    return response

分页:

from rest_framework import pagination, serializers

class CustomMetaSerializer(serializers.Serializer):
    next_page = pagination.NextPageField(source='*')
    prev_page = pagination.PreviousPageField(source='*')
    record_count = serializers.Field(source='paginator.count')

class CustomPaginationSerializer(pagination.BasePaginationSerializer):
    # Takes the page object as the source
    meta = CustomMetaSerializer(source='*')
    results_field = 'paginated_results'

这篇关于将根元素添加到json响应(django-rest-framework)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆