2009-03-09 21 views
3

Insinが前のquestionに関連してくれたことに感謝します。Djangoフォームプレビュー - 'cleaned_data'の操作方法

彼の答えはうまくいきましたが、私は 'cleaned_data'の提供、またはより正確にはどのように使用するのか困惑していますか?クイックリファレンスについては

class RegistrationFormPreview(FormPreview): 
    preview_template = 'workshops/workshop_register_preview.html' 
    form_template  = 'workshops/workshop_register_form.html' 

    def done(self, request, cleaned_data): 
     # Do something with the cleaned_data, then redirect 
     # to a "success" page. 

     registration   = Registration(cleaned_data) 
     registration.user  = request.user 
     registration.save() 
     # an attempt to work with cleaned_data throws the error: TypeError 
     # int() argument must be a string or a number, not 'dict' 
     # obviously the fk are python objects(?) and not fk_id 
     # but how to proceed here in an easy way? 



     # the following works fine, however, it seems to be double handling the POST data 
     # which had already been processed in the django.formtools.preview.post_post 
     # method, and passed through to this 'done' method, which is designed to 
     # be overidden. 
     ''' 
     form     = self.form(request.POST) # instansiate the form with POST data 
     registration   = form.save(commit=False) # save before adding the user 
     registration.user  = request.user    # add the user 
     registration.save()         # and save. 
     ''' 

     return HttpResponseRedirect('/register/success') 

、ここpost_post方法の内容です:

def post_post(self, request): 
    "Validates the POST data. If valid, calls done(). Else, redisplays form." 
    f = self.form(request.POST, auto_id=AUTO_ID) 
    if f.is_valid(): 
     if self.security_hash(request, f) != request.POST.get(self.unused_name('hash')): 
      return self.failed_hash(request) # Security hash failed. 
     return self.done(request, f.cleaned_data) 
    else: 
     return render_to_response(self.form_template, 
      {'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state}, 
      context_instance=RequestContext(request)) 
+0

@Antoniusあなたは、Pythonのスタイルガイドを見て取る必要があります:あなたは良いの助けを得るときhttp://www.python.org/dev/peps/pep-0008/ – orokusaki

答えて

9

私はあなたが前のModelFormで、ここでやっていることを試みたことがありませんが、あなたは使用することができるかもしれません**ご登録のコンストラクタに予想されるキーワード引数にあなたのcleaned_data辞書を拡大するオペレータ:

registration = Registration (**cleaned_data) 

コンストラクタモデルクラスには、そのĐàキーワード引数を取りますngoのModelメタクラスは、結果として得られるオブジェクトのインスタンスレベルの属性に変換されます。 **演算子はPythonに辞書をそれらのキーワード引数に展開するように指示する呼び出し規約です。言い換えれば

...あなたが現在やっていること

はこれに等しいです:

registration = Registration ({'key':'value', ...}) 

コンストラクタは、その辞書ではなくキーワード引数として期待するので、あなたが望むものではありませんキーワード引数が含まれています。

は何をやっているしたいことはこれに似ているこの

registration = Registration (key='value', ...) 

です:再び

registration = Registration (**{'key':'value', ...}) 

を、私はそれを試したことがありませんが、それは限りうまくいくように思えます登録コンストラクタでは期待していない新しい属性を追加するなど、フォームで気をつけているわけではありません。その場合は、これを行う前にcleaned_dataディクショナリの項目を変更する必要があります。

フォームプレビューユーティリティを使用して、ModelFormsに固有の機能の一部を失っているようです。おそらく、あなたのユースケースをDjangoのメーリングリストに持ち帰り、このAPIがModelFormsでうまく動作するようになる可能性があるかどうかを確認する必要があります。

編集

私が上記した内容の短い、あなたはいつも、単に「手で」あなたのcleaned_data辞書からフィールドを抽出してもあなたの登録のコンストラクタにそれらを渡すが、あなたの注意点を持つことができます新しいフィールドをモデルに追加するときにこのコードを更新することを忘れないでください。

registration = Registration (
    x=cleaned_data['x'], 
    y=cleaned_data['y'], 
    z=cleaned_data['z'], 
    ... 
) 
+0

ジーを、それはとても簡単です!よくやってくれてありがとう...私はそれらの**が何のために思っていた! (それは** btwを必要とする唯一のモデムでした) –

+0

あなたがしようとしているのは、フォームデータに基づいてモデルを作成することです。 –

+0

@Carl明確にするために、彼はModelFormを使用していますが、FormPreviewを中間で使用すると、冗長な処理をしなくてもModelFormの特定の機能(オブジェクトの構築とコミット)を使用できなくなります。これが私のユースケースをDjangoのメーリングリストに持ち込むことを提案した理由です。 –

関連する問題