0

再利用可能なDjangoアプリになりたいと思っているものを書きましたが、投稿フォームの処理を柔軟にする方法については少し難問があります。ビューコードの簡略化されたバージョンは次のようになります。

def do_form(request, entity_id, template_name, success_url):

    form = MyForm(request.POST or None)

    if request.method =='POST':
        if form.is_valid():

            #do some business logic

            return HttpResponseRedirect(finished_url)
    return render_to_response(template_name, 
                              {'form': form},
                             context_instance=RequestContext(request))

JamesBennetsの本「PracticalDjangoProjects」のアドバイスに従ったので、url confでテンプレートと成功URLを構成できるようになりました。たとえば、私のurlconfは次のようになります。

urlpatterns = patterns('myapp.views',


          url(r'^do/(?P<entity_id>\d+)/$', 
          view = 'do_form',
          name = 'do_form_view',
          kwargs={'template_name':'form.html',
                    'success_url':'/finish/'},),

          url(r'^finish/$', 
          view = 'finish',
          name = 'finish_view')
)

/continue/<workflow_id>/これはすべて非常にうまく機能していますが、実際のアプリケーションでこれを使用するようになったとき、このフォームがワークフローの途中にあることに気付き、成功URLを次のようにしたいと思います。問題は、url confにハードコードされたURLしか含めることができず、do_formコードを押すたびにworkflow_idが変化することです。

誰かがこれを回避する方法を提案できますか?

4

3 に答える 3

1

架空の「柔軟な」success_urlをビューに渡す場合、そのビューは目的の識別子を提供する必要があります。したがって、URLとビューが一致しない場合、2つの間に「契約違反」が発生することは避けられません。

したがって、柔軟なURLを使用する場合は、何らかの契約を適用する必要があります。URLの特別な構文を使用してこれを行うと、一般性が失われることはありません。

  'finished_url':  '/finish/<workflow_id>/'

次に、もちろん、ビューは、コントラクトの側面を尊重するために、文字列の置換によって変数をインスタンス化する必要があります。

  return HttpResponseRedirect(finished_url)

あなたが持っているでしょう

  return HttpResponseRedirect(finished_url.replace('<workflow_id>', WorkflowID))

これにより、物事がかなり単純に保たれるはずです。

コードを再利用するときは、そのアプリがワークフローIDを呼び出すために使用するものである<workflow_id>ことに注意する必要があります。そのため、の代わりに、または多分などの複雑な文字列を使用します。workflow_idid$1

編集:次のステップ(finishの引数でワークフローIDをインターセプトする)のコードを追加するつもりでしたが、keithxm23が私を打ち負かしたことがわかります:-)

于 2012-09-11T19:12:35.890 に答える
1

以下を変更することでそれを達成することができます。

views.pydo_form()に 変更しますreturn HttpResponseRedirect

return HttpResponseRedirect('/continue/%s' %(workflowid))

そしてurls.pyで、あなたは持つことができます

url(r'^continue/(?P<workflowid>\d+)/$', 
          view = 'continue',
          name = 'continue_view')

そしてviews.pycontinue()のビューのために

def continue(request, workflowid=None):
 ...

このように..番号なしでURLにアクセスするときはいつでも/continue/、workflowidは。に等しくなりNoneます。たとえば、などのワークフローIDがアタッチされている場合は/continue/23/、ビュー内continue()で変数を介してそのIDにアクセスできますworkflowid

于 2012-09-11T19:09:40.810 に答える
0

人々が何年もの間Djangoの関数ベースのジェネリックビューを「オーバーライド」してきたのと同じ方法でそれを行うことができます。ビューを別のビューでラップするだけです。

def custom_do_form(request, entity_id, template_name, success_url):
    template_name = some_method_to_get_template()
    return do_form(request, entity_id, template_name, success_url)
于 2012-09-11T19:03:47.857 に答える