使用django-piston时出现400 Bad Request错误

Che*_*ezo 11 python django rest json django-piston

我正在尝试使用Piston为Django提供REST支持.我根据提供的文档实现了我的处理程序.问题是我可以"读取"和"删除"我的资源,但我无法"创建"或"更新".每次我点击相关的api我得到400 Bad request Error.

我已经使用这个常用的代码片段扩展了csrf的Resource类:

class CsrfExemptResource(Resource):
    """A Custom Resource that is csrf exempt"""
    def __init__(self, handler, authentication=None):
        super(CsrfExemptResource, self).__init__(handler, authentication)
        self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)
Run Code Online (Sandbox Code Playgroud)

我的类(代码片段)看起来像这样:

user_resource = CsrfExemptResource(User)

class User(BaseHandler):
    allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')

    @require_extended
    def create(self, request):
        email = request.GET['email']
        password = request.GET['password']
        phoneNumber = request.GET['phoneNumber']
        firstName = request.GET['firstName']
        lastName = request.GET['lastName']
        self.createNewUser(self, email,password,phoneNumber,firstName,lastName)
        return rc.CREATED
Run Code Online (Sandbox Code Playgroud)

请让我知道如何使用POST操作使create方法工作?

小智 10

这种情况正在发生,因为Piston不喜欢ExtJS在标题的内容类型中放置"charset = UTF-8"这一事实.

通过添加一些中间件来轻松修复以使内容类型更加活塞友好,在应用程序基目录中创建一个名为middleware.py的文件:

class ContentTypeMiddleware(object):

    def process_request(self, request):
        if request.META['CONTENT_TYPE'] == 'application/x-www-form-urlencoded; charset=UTF-8':
            request.META['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
        return None
Run Code Online (Sandbox Code Playgroud)

然后只需在settings.py中包含此中间件:

MIDDLEWARE_CLASSES = (
    'appname.middleware.ContentTypeMiddleware',
)
Run Code Online (Sandbox Code Playgroud)


Eri*_*oni 7

建议的解决方案仍然不适合我(django 1.2.3 /活塞0.2.2)所以我调整了joekrell解决方案,这最终工作(我只使用POST和PUT,但可能你可以添加其他动词到列表):

class ContentTypeMiddleware(object):

def process_request(self, request):

    if request.method in ('POST', 'PUT'):
        # dont break the multi-part headers !
        if not 'boundary=' in request.META['CONTENT_TYPE']:
            del request.META['CONTENT_TYPE']
Run Code Online (Sandbox Code Playgroud)

有:

MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware',
)
Run Code Online (Sandbox Code Playgroud)

我没有注意到任何副作用,但我不能保证它是防弹的.

  • 是的,你的解决方案也适用于我(Django 1.3,Piston 0.2.2).一般来说,看起来Piston变成了废弃物 - 它在很长一段时间内都没有更新. (2认同)

TIM*_*MEX 1

在 utils.py 中,更改此项。

def content_type(self):
    """
    Returns the content type of the request in all cases where it is
    different than a submitted form - application/x-www-form-urlencoded
    """
    type_formencoded = "application/x-www-form-urlencoded"

    ctype = self.request.META.get('CONTENT_TYPE', type_formencoded)

    if ctype.strip().lower().find(type_formencoded) >= 0:
        return None

    return ctype
Run Code Online (Sandbox Code Playgroud)

https://bitbucket.org/jespern/django-piston/issue/87/split-charset-encoding-form-content-type