适用于Android客户端的Dj​​ango Rest Framework响应的通用JSON格式

时间:2018-02-23 04:46:20

标签: android json django mobile django-rest-framework

我正在使用Djnago Rest Framework为Android应用程序开发其余api。安卓人员告诉我,如果我能以一种通用格式提供回复会很好,比如

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

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

提前致谢。

3 个答案:

答案 0 :(得分:5)

如果您使用基于类的视图说<!DOCTYPE html> <html> <head> <title>TodoList App</title> <!-- bootstrap cdn --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <!-- google fonts --> <link href="https://fonts.googleapis.com/css?family=Righteous" rel="stylesheet"> <style type="text/css"> /*variables*/ :root { --righteous-font: 'Righteous', cursive; } body { /*background-color: #536691;*/ background-image: url("http://pctechtips.org/apps/conf/img/Chicago-Wallpaper-3.jpg"); min-height: 100vh; z-index: -10; background-position: center; background-repeat: no-repeat; background-size: cover; color: white; font-size: 1.3rem; } .hero { position: absolute; min-height: 100vh; min-width: 100vw; top: 0; bottom: 0; background-color: rgba(31, 34, 118, 0.5); } h1 { margin-top: 12rem; margin-bottom: 0px; padding-bottom: 0px; font-family: var(--righteous-font); } .lead { font-size: 1.5rem; font-family: var(--righteous-font); } hr { margin-top: 2rem; border: 1px solid white; display: none; } ul { /*border-top: 2px solid white;*/ margin-top: 2rem; list-style: none; /*display: none;*/ } li { border-bottom: 1px solid white; padding: 0.5rem 0 0.5rem 0; margin: 0 1rem 0 1rem; } .checkboxes { float: right; line-height: 15px; width: 17px; height: 17px; background-color: #e9ecef; border: 1px solid #e9ecef; border-radius: 3px; } </style> </head> <body> <div class="hero"> <div class="container"> <h1 class="display-2 text-center">TodoList</h1> <p class="lead text-center">Welcome to my todoList applications</p> <div class="row"> <form id="form" class="col-8 mx-auto"> <div class="input-group"> <input id="input" class="form-control" placeholder="Enter todo list item" value="this is a todo list item for me todo"> <span> <button id="btn" type="button" class="btn btn-primary">Submit</button> </span> </div> </form> </div> <hr> <div class="row"> <ul id="list" class="list col-8 mx-auto"> <!-- <li>this is a todo item <input type="checkbox" class="checkbox"></li> <li>this is a todo item <input type="checkbox" class="checkbox"></li> --> </ul> </div> </div> </div> <!-- todolist app functionality --> <script type="text/javascript"> window.onload = function() { // variables var submitBtn = document.getElementById("btn"); var ul = document.getElementById("list"); var todoItem = document.getElementById("input"); var hr = document.getElementById("hr"); var id = 1; //button event listener submitBtn.addEventListener("click", addTodoItem); //dynamically added checkbox event listener $(document).on("click", ".checkboxes", function() { var boxId = $(this).attr("id"); var num = boxId.split("-")[1]; console.log("checkbox: "+num); // checkedItem(num); var checkedLi = document.getElementById("li-"+num); checkedLi.style.textDecoration = "line-through"; }); /* add todo items to list */ function addTodoItem() { console.log(todoItem.value); if(todoItem.value === "") { alert("Enter some text!"); } else { if(ul.style.borderTop == "") { ul.style.borderTop = "2px solid white"; } var li = document.createElement("li"); li.id = "li-"+id var text = document.createTextNode(todoItem.value); var checkbox = document.createElement("input"); checkbox.id = "checkbox-"+id; checkbox.className = "checkboxes"; checkbox.type = "checkbox"; li.appendChild(text); li.appendChild(checkbox); ul.appendChild(li); id++; } //reset form document.getElementById("form").reset(); } /* check item completed */ function checkedItem(num) { } } </script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> </body> </html> 或一般视图,编写您自己的响应函数将无济于事。我认为更好的方法是编写custom renderer用于格式化成功回复,并custom exception handler用于有错误的回复。此实现为您提供单点控制所有响应,而无需更改现有视图。这是我的一个项目的示例代码。您需要根据您的要求进行修改。

自定义渲染器

APIView

自定义异常处理程序

#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

答案 1 :(得分:1)

您可以为自定义的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)

答案 2 :(得分:-1)

是实现共同回应的正确方法。

为此,您必须创建一个Generic类,其中一个常用于处理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;
    }
}