使用django-piston时出现400错误

11 投票
7 回答
4518 浏览
提问于 2025-04-16 09:04

我正在尝试使用Piston为Django提供REST支持。根据提供的文档,我已经实现了我的处理程序。问题是,我可以“读取”和“删除”我的资源,但无法“创建”或“更新”。每次我访问相关的API时,都会收到一个400错误,表示请求错误。

为了处理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)

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

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

请告诉我如何使用POST操作让创建方法正常工作?

7 个回答

4

我把其他人说的一些内容结合起来了,并且增加了对任何内容类型的支持,比如说json格式...

class ContentTypeMiddleware(object):
    def process_request(self, request):
        if request.method in ('POST', 'PUT') and request.META['CONTENT_TYPE'].count(";") > 0:
            request.META['CONTENT_TYPE'] = [c.strip() for c in request.META['CONTENT_TYPE'].split(";") ][0]
        return None
7

我试过的解决方案对我来说还是不管用(我用的是django 1.2.3和piston 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']

用这个:

MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware',
)

我没有发现有什么副作用,但我不能保证它绝对没问题。

10

这个问题发生是因为Piston不喜欢ExtJS在头部的内容类型中加上“charset=UTF-8”。

解决这个问题很简单,只需要添加一些中间件,让内容类型更适合Piston。你可以在应用的根目录下创建一个叫做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

然后只需在你的settings.py文件中包含这个中间件:

MIDDLEWARE_CLASSES = (
    'appname.middleware.ContentTypeMiddleware',
)

撰写回答