在Pyramid中如何返回400响应和JSON数据?

16 投票
3 回答
9360 浏览
提问于 2025-04-16 21:53

我有以下的jquery代码:

$.ajax({
    type: 'POST',
    url: url,
    data: data,
    dataType: 'json',
    statusCode: {
        200: function (data, textStatus, jqXHR) {
                console.log(data);
            },
        201: function (data, textStatus, jqXHR) {
                 log(data);
            },
        400: function(data, textStatus, jqXHR) {
                log(data);
            },
    },
});

这里的400是用来表示后端(Pyramid)验证失败的情况。那么从Pyramid中,我该如何返回一个HTTPBadRequest()的响应,同时带上一个包含验证错误的json数据呢?我试过类似这样的代码:

response = HTTPBadRequest(body=str(error_dict)))
response.content_type = 'application/json'
return response

但是当我在firebug中查看时,它返回了400(错误请求),这很好,但它从上面的data.responseText中却没有解析出json响应。

3 个回答

0

你可以这样修改响应的状态码:request.response.status_code = 400。下面的例子对我来说是有效的。

@view_config(route_name='qiwiSearch', request_method='GET', renderer='json')
def qiwiSearchGet(request):
    schema = SchemaQiwiSearchParams()
    try:
        params = schema.deserialize(request.GET)
    except colander.Invalid, e:
        errors = e.asdict()
        request.response.status_code = 400
        return dict(code=400, status='error', message=unicode(errors))

    log.debug(u'qiwiSearchGet: %s' % params)
    return dict(code=200, status='success', message='', data=[1,2,3])
3

我找到了一种更通用的方法,比接受的答案简单,我用这段代码实现的。

我在我的视图中包含了exception_response。

from pyramid.httpexceptions import exception_response

在需要的地方,我会抛出400的异常。

 raise exception_response(400)

在我的异常处理脚本中,我捕获所有异常,以返回通用的json格式,同时我会特别处理400的异常,返回一个具体的json格式。

from pyramid.view import exception_view_config

from pyramid.httpexceptions import (
    HTTPException,
    HTTPBadRequest
)


@exception_view_config(HTTPException, renderer='json')
def exc_view_exception(message, request):
    return {'error': str(message)}


@exception_view_config(HTTPBadRequest, renderer='json')
# Exception 400 bad request
def exc_view_bad_request(message, request):
    body = {
        "message": str(message),
        "status": 400
    }
    request.response.status = 400
    return body
31

首先,你应该用一个叫做json的库来把error_dict转换成一种可以存储和传输的格式。

import json
out = json.dumps(error_dict)

因为你没有提供你的视图是怎么设置的背景信息,我只能告诉你我会怎么做:

@view_config(route_name='some_route', renderer='json')
def myview(request):
    if #stuff fails to validate:
        error_dict = # the dict
        request.response.status = 400
        return {'errors': error_dict}

    return {
        # valid data
    }

如果你想自己创建响应的话,可以这样做:

response = HTTPBadRequest()
response.body = json.dumps(error_dict)
response.content_type = 'application/json'
return response

要解决这个问题,不要只看jQuery是否正常工作,而是要自己检查请求,看看Pyramid是否正常运行,或者是不是其他问题。

curl -i <url>

你甚至可以在浏览器里打开调试工具,看看响应中返回了什么。

撰写回答