访问request.DATA时出现Django REST Framework ParseError

时间:2014-01-12 10:29:42

标签: django django-rest-framework

当客户端使用无效的JSON提交请求时,如何构建基于函数的视图以返回HTTP 400?

REST框架Request documentation声明在访问包含无效JSON的ParseError时可能会引发request.DATA。文档继续说明如果使用@api_view修饰了视图函数,将捕获错误并将HTTP 400错误请求返回给客户端。

在我创建的视图中,当我访问request.DATA时,我收到的是HTTP 500 ParseError而不是预期的HTTP 400。

我的观点结构如下:

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

from serializers import PersonSerializer

@api_view(['POST'])
def person_list(request):

    # Deserialize the incoming JSON into a Person object.
    # FIXME: ParseError raised here if JSON is invalid!
    person = PersonSerializer(data=request.DATA)

    # Ensure that the request contains valid data.
    if not person.is_valid():
        return Response(person.errors, status=status.HTTP_400_BAD_REQUEST)

    # Save the Person object into the Mongo backend.
    person.save()

    return Response(person.data, status=status.HTTP_201_CREATED)

我的序列化程序结构如下:

  from rest_framework import serializers

  class PersonSerializer(serializers.Serializer):
      name = serializers.CharField()
      surname = serializers.CharField()
      age = serializers.IntegerField()

      def restore_object(self, attrs, instance):
          """Given a dictionary of deserialized field values or create a new
          model instance.
          """
          return Event(**attrs)

请注意,我没有使用ModelSerializer,因为模型是由mongoengine而不是Django ORM提供的。

如果我向视图发送了无效的JSON字符串(例如,没有任何内容的POST)或使用此字符串:{"name": "Alice", "surname" "Test", "age": 30}(请注意:之后缺少的冒号"surname")Django将返回带有以下内容的HTTP 500:

ParseError at /people/
No exception message supplied

即使我尝试访问request.DATA而未将其传递给PersonSerializer,也会引发ParseError

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

我无法重现这一点。

我运行了这段代码:

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view(['POST'])
def person_list(request):

    data = request.DATA
    print data

    return Response({}, status=200)

from rest_framework.test import APITestCase
from django.test.utils import override_settings

class TestFoo(APITestCase):
    from django.conf.urls import patterns, url
    urls = patterns('',
        url(r'^test$', person_list),
    )

    @override_settings(APPEND_SLASH=False)
    def test_thing(self):
        bad_json = '{"name": "Alice", "surname" "Test", "age": 30}'
        resp = self.client.post('/test', bad_json, content_type='application/json')
        print resp.status_code
        print resp

得到了这个输出:

400
Vary: Accept, Cookie
Content-Type: application/json
Allow: POST, OPTIONS

{"detail": "JSON parse error - Expecting ':' delimiter: line 1 column 29 (char 28)"}

您使用的是哪个版本的rest_framework?你能提供一些包含失败测试的代码吗?你的settings.REST_FRAMEWORK中有什么东西可能影响这个吗?