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

时间:2010-12-27 07:50:52

标签: python django json rest 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)

我的课程(代码段)如下所示:

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操作使create方法正常工作?

7 个答案:

答案 0 :(得分: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

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

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

答案 1 :(得分: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']

使用:

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

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

答案 2 :(得分: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

答案 3 :(得分:4)

我认为Eric的解决方案效果最好,但在管理员保存时却遇到了问题。如果有其他人遇到它,这个调整似乎解决了它:

class ContentTypeMiddleware(object):

    def process_request(self, request):
        if request.method in ('POST') and not 'boundary=' in request.META['CONTENT_TYPE']:
            request.META['CONTENT_TYPE'] = [c.strip() for c in request.META['CONTENT_TYPE'].split(";") ][0]
        return None

答案 4 :(得分: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

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

答案 5 :(得分:1)

这是一个解决方案,经过调整后对我有用:

class ContentTypeMiddleware(object):

    def process_request(self, request):
        if 'charset=UTF-8' in request.META['CONTENT_TYPE']:
            request.META['CONTENT_TYPE'] = request.META['CONTENT_TYPE'].replace('; charset=UTF-8','')
        return None

答案 6 :(得分:0)

我们有一个资源只是根据请求凭据和PUT更新时间戳。事实证明,活塞不喜欢没有有效载荷的PUT。添加空字符串有效负载''修好了。

快速谷歌搜索表明,像Apache这样的其他系统也可能不喜欢没有有效载荷的PUT。