I am trying to use Piston to provide REST support to Django. I have implemented my handlers as per the documentation provided . The problem is that i can "read" and "delete" my resource but i cannot "create" or "update". Each time i hit the relevant api i get a 400 Bad request Error.
我正在尝试用活塞给Django提供REST支持。我已经按照提供的文档实现了我的处理程序。问题是我可以“读”和“删除”我的资源,但是我不能“创建”或“更新”。每次我点击相关的api,就会得到400个错误请求。
I have extended the Resource class for csrf by using this commonly available code snippet:
我使用这个常用的代码片段扩展了csrf的资源类:
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)
My class (code snippet) looks like this:
我的类(代码片段)如下:
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
Please let me know how can i get the create method to work using the POST operation?
请告诉我如何使用POST操作获得create方法?
7 个解决方案
#1
10
This is happening because Piston doesn't like the fact that ExtJS is putting "charset=UTF-8" in the content-type of the header.
这是因为活塞不喜欢ExtJS在标题的内容类型中加入“charset=UTF-8”。
Easily fixed by adding some middleware to make the content-type a bit more Piston friendly, create a file called middleware.py in your application base directory:
通过添加一些中间件使内容类型更加友好,从而很容易修复,创建一个称为中间件的文件。您的应用程序基目录中的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
Then simply include this middleware in your settings.py:
然后将这个中间件包含在您的设置中。
MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware',
)
#2
7
Proposed solutions still did not work for me (django 1.2.3/piston 0.2.2) so I've tweaked joekrell solution and this finally works (I'm only using POST and PUT, but presumably you can add other verbs to the list):
所提出的解决方案对我来说仍然不起作用(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']
with:
:
MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware',
)
I haven't noticed any side-effect, but I can't promise it's bullet-proof.
我没有注意到任何副作用,但我不能保证它是防弹的。
#3
4
I have combined some of what other people have said, and added support for any content type, json for instance...
我结合了其他人所说的内容,并添加了对任何内容类型的支持,例如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
#4
4
I thought Eric's solution worked the best but then ran into problems when saving things in admin. This tweak seems to fix it if anyone else comes across it:
我认为Eric的解决方案是最好的,但是在admin中保存东西时遇到了问题。如果有人遇到这种情况,这一调整似乎可以解决这个问题:
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
#5
1
In utils.py, change this.
在跑龙套。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
https://bitbucket.org/jespern/django-piston/issue/87/split-charset-encoding-form-content-type
#6
1
This is solution which worked for me, after a tweak:
这是一个对我有用的解决方案,经过调整:
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
#7
0
We had a resource that was simply updating a timestamp based on the request credentials and PUT. It turns out that Piston does not like PUT without a payload. Adding an empty string payload '' fixed it.
我们有一个资源,它只是基于请求凭据和PUT更新时间戳。结果是活塞不喜欢没有有效载荷。添加空字符串有效载荷“修复了它”。
A quick Google search indicates that other systems like Apache may not like PUT without a payload, as well.
快速的谷歌搜索表明,像Apache这样的其他系统可能也不喜欢没有负载的PUT。
#1
10
This is happening because Piston doesn't like the fact that ExtJS is putting "charset=UTF-8" in the content-type of the header.
这是因为活塞不喜欢ExtJS在标题的内容类型中加入“charset=UTF-8”。
Easily fixed by adding some middleware to make the content-type a bit more Piston friendly, create a file called middleware.py in your application base directory:
通过添加一些中间件使内容类型更加友好,从而很容易修复,创建一个称为中间件的文件。您的应用程序基目录中的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
Then simply include this middleware in your settings.py:
然后将这个中间件包含在您的设置中。
MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware',
)
#2
7
Proposed solutions still did not work for me (django 1.2.3/piston 0.2.2) so I've tweaked joekrell solution and this finally works (I'm only using POST and PUT, but presumably you can add other verbs to the list):
所提出的解决方案对我来说仍然不起作用(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']
with:
:
MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware',
)
I haven't noticed any side-effect, but I can't promise it's bullet-proof.
我没有注意到任何副作用,但我不能保证它是防弹的。
#3
4
I have combined some of what other people have said, and added support for any content type, json for instance...
我结合了其他人所说的内容,并添加了对任何内容类型的支持,例如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
#4
4
I thought Eric's solution worked the best but then ran into problems when saving things in admin. This tweak seems to fix it if anyone else comes across it:
我认为Eric的解决方案是最好的,但是在admin中保存东西时遇到了问题。如果有人遇到这种情况,这一调整似乎可以解决这个问题:
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
#5
1
In utils.py, change this.
在跑龙套。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
https://bitbucket.org/jespern/django-piston/issue/87/split-charset-encoding-form-content-type
#6
1
This is solution which worked for me, after a tweak:
这是一个对我有用的解决方案,经过调整:
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
#7
0
We had a resource that was simply updating a timestamp based on the request credentials and PUT. It turns out that Piston does not like PUT without a payload. Adding an empty string payload '' fixed it.
我们有一个资源,它只是基于请求凭据和PUT更新时间戳。结果是活塞不喜欢没有有效载荷。添加空字符串有效载荷“修复了它”。
A quick Google search indicates that other systems like Apache may not like PUT without a payload, as well.
快速的谷歌搜索表明,像Apache这样的其他系统可能也不喜欢没有负载的PUT。