11

我正在尝试使用 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 操作让 create 方法工作?

4

7 回答 7

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',
)
于 2011-03-25T00:58:27.390 回答
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',
)

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

于 2011-04-09T09:40:23.623 回答
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
于 2011-10-05T16:13:34.410 回答
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
于 2011-08-24T14:32:40.147 回答
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

于 2011-01-21T19:04:06.390 回答
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
于 2013-10-23T12:58:58.337 回答
0

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

快速的 Google 搜索表明,Apache 等其他系统可能也不喜欢没有有效负载的 PUT。

于 2014-10-25T00:23:23.157 回答