2010-12-27 6 views
11

ピストンを使用してDjangoにRESTサポートを提供しようとしています。 提供されたドキュメントに従ってハンドラを実装しました。 問題は、自分のリソースを「読み込み」、「削除」できますが、「作成」や「更新」できないことです。 関連するAPIをヒットするたびに、400の不正なリクエストエラーが発生します。django-pistonを使用中に400の不正リクエストエラーが発生する

私は、この一般的に利用可能なコードスニペットを使用することによって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) 

私のクラス(コードスニペット)は次のようになります。

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メソッドを取得しますか?

+0

さて、リソースクラスの拡張子を使用する代わりに、設定ファイルから "django.middleware.csrf.CsrfViewMiddleware"をコメントアウトしました。 – Cheezo

+0

"作成"または "更新"に対応する "PUT"または "POST" HTTP操作をどのように試みていますか?このクライアントサイドのコードが正しい、有効なHTTPリクエストを作成していることをどのように知っていますか? –

+0

POSTの場合、私は明示的にPOST要求を作成することができるrestclient WizTools.orgを使用します。atleast要求を通過していると確信しています。 – Cheezo

答えて

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

10

ピストンがExtJSには、ヘッダのコンテンツタイプの「文字セット= 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 

は、単にあなたの設定でこのミドルウェアを含めます.py:

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

提案されたソリューションは、まだ私のために動作しませんでした(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', 
) 

私は、任意の副作用を気づいていないが、私はそれが防弾の約束はできません。私は...

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 
+2

はい、あなたのソリューションは私のためにも機能しました(Django 1.3、Piston 0.2.2)。一般的に、ピストンは放棄されたように見えます。長い間更新されていませんでした。 –

4

私はエリックのソリューションが最善を働いたと思ったが、その後の保存時に問題に遭遇しました管理者のものこの調整は、他の誰がそれを越えていた場合、それを修正するようだ:

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 
+0

これは最適なソリューションでした。ありがとうございました。 – GivP

+0

POST用にこれを使用すると他のものが壊れましたが、PUT用に問題を修正しました –

4

を他の人が言ったことのいくつかを組み合わせ、そして、例えばJSONを任意のコンテンツタイプのサポートを追加した

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 
0

我々は、単にベースのタイムスタンプを更新されたリソースを持っていました要求資格とPUTについてPistonはペイロードのないPUTを好まないことが判明しました。空の文字列ペイロードを追加すると ''それが修正されました。

Apacheをはじめとする他のシステムでも、ペイロードのないPUTが好まれない可能性があることがGoogleの迅速な検索で分かります。