用于 Android 客户端的 Django Rest Framework 响应的通用 JSON 格式

Posted

技术标签:

【中文标题】用于 Android 客户端的 Django Rest Framework 响应的通用 JSON 格式【英文标题】:Common JSON Format for Django Rest Framework responses for Android client 【发布时间】:2018-08-03 02:56:52 【问题描述】:

我正在使用 Djnago Rest Framework 为 android 应用程序开发其余 API。 android 的人告诉我,如果我能以通用格式提供响应,那就太好了,比如


   “Status”:””,
   “Message”:””,
   “Data”:[]

伙计们,这是正确的方法吗?如果是这样,如何实现这一目标?我的假设是使用中间件是一种选择。

提前致谢。

【问题讨论】:

使用Serializers, django-rest-framework.org/api-guide/serializers @JerinPeterGeorge,所以你建议我按视图处理这个? 【参考方案1】:

是的,这是实现共同响应的正确方法。

为此,您必须创建一个在处理 API 响应时常用的通用类,您只需将不同的列表作为您的 API 响应传递。

您的通用类应该如下所示。

public class Status<T> 
    @SerializedName("Message")
    @Expose
    private String message;
    @SerializedName("Status")
    @Expose
    private String status;
    @SerializedName("Data")
    @Expose
    private T result;

    public String getMessage() 
        return message;
    

    public void setMessage(String message) 
        this.message = message;
    

    public String getStatus() 
        return status;
    

    public void setStatus(String status) 
        this.status = status;
    

    public T getResult() 
        return result;
    

    public void setResult(T result) 
        this.result = result;
    

【讨论】:

感谢您的回复@mehul-kabaria。但实际上我问的是在 Django 端实现它。【参考方案2】:

您可以为自定义的 django rest 响应编写函数并重用它。以下是您可以执行此操作的方法。

def custom_response(status_code=status.HTTP_200_OK, message='', data):
    return Response(
        
             "status": status_code, 
             "message": message, 
              "data": data
        ,
        status=status.HTTP_200_OK
    )

这样,请求的响应代码将始终为 200,但您可以在 status_code 值中提供您想要的任何代码。你可以这样使用。

return custom_response(status_code=status.HTTP_200_OK, message='Data saved successfully', data=my_serialized_data)

【讨论】:

您在您的应用程序中采用这种方法吗?我的意思是,您知道是否有必要为移动客户端自定义对这种格式的响应? 是的。我也在为移动客户端开发 apis 并遵循相同的方法。 所以你在视图中添加条件语句来检查错误或成功? 您需要验证提供的数据,以便每个参数都符合要求的形式,以免发生服务器错误。如果出现服务器错误,您的视图将返回状态码不是 200 的响应,并且您的应用将崩溃。【参考方案3】:

如果您使用基于类的视图,比如APIView 或通用视图,编写您自己的响应函数将无济于事。我认为更好的方法是写custom renderer 格式化成功的响应和custom exception handler 用于错误的响应。此实现为您提供了一个单点来控制所有响应,而无需更改您已经存在的视图。这是我的一个项目的示例代码。您需要根据您的要求对其进行修改。

自定义渲染器

#renderers.py
class CustomJSONRenderer(JSONRenderer):

def render(self, data, accepted_media_type=None, renderer_context=None):

    response_data = 'message': '', 'errors': [], 'data': data, 'status': 'success'

    getattr(renderer_context.get('view').get_serializer().Meta,'resource_name', 'objects')

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

    return response

自定义异常处理程序

# custom_exception_handler.py
def custom_exception_handler(exc, context):
  # Call REST framework's default exception handler first,
  # to get the standard error response.
  response = exception_handler(exc, context)

  # Now add the HTTP status code to the response.
  if response is not None:

    errors = []
    message = response.data.get('detail')
    if not message:
        for field, value in response.data.items():
            errors.append(" : ".format(field, " ".join(value)))
        response.data = 'data': [], 'message': 'Validation Error', 'errors': errors, 'status': 'failure'
    else:
        response.data = 'data': [], 'message': message, 'error': [message], 'success': 'failure'

  return response

覆盖REST_FRAMEWORK 设置以使用这些渲染器和异常处理程序。

REST_FRAMEWORK = 
  # Add custom renderer.
  'DEFAULT_RENDERER_CLASSES'=(
              'path.to.CustomJSONRenderer',
              'rest_framework.renderers.JSONRenderer',
              'rest_framework.renderers.BrowsableAPIRenderer'),
  # Add cutom exception handler
  'EXCEPTION_HANDLER': 'path.to.custom_exception_handler'
   

【讨论】:

您需要在custom_exception_handler 中查看accepted_renderer。如果响应错误,您需要设置context['request'].accepted_renderer = renderers.JSONRenderer()(如果当前使用的渲染器是您的自定义类的实例:if isinstance(context['request'].accepted_renderer, CustomJSONRenderer))以呈现正确的响应,否则将响应嵌套字典(内部数据如示例)。 CustomJSONRenderer 中的这一行是做什么用的? getattr(renderer_context.get('view').get_serializer().Meta,'resource_name', 'objects')

以上是关于用于 Android 客户端的 Django Rest Framework 响应的通用 JSON 格式的主要内容,如果未能解决你的问题,请参考以下文章

django能开发手机客户端么

带有 Android 客户端的 Java 游戏服务器

用于 Google 云消息传递客户端的 BroadcastReceiver 或 GCMBroadcastReceiver?

Google API - Android BigQuery 客户端的应用级授权

如何从 android 客户端进行经过身份验证的 django rest api 调用?

django学习之- session