2009-07-04 30 views
10

ビューをレンダリングした後は、どうすればよいですか? (Django)

return render_to_response() 

これを行う唯一の方法は信号ですか?私はカスタムシグナルを書く必要がありますか、または十分な情報を私に与えるrequest_finishedですか?基本的には、どのページがレンダリングされたのかを知り、それに応じてアクションを実行する必要があります。

ありがとうございました。

コメントからの更新:私はページのレンダリングを保持したくないので、まずページをレンダリングしてから、そのアクションを行いたいと思います。

+2

。レンダリングしようとしているページが分かります。ちょうどその行動をしてください。ビュー機能に余分なアクションを挿入するだけの理由はありますか?あなたがしようとしていることについてのヒントを提供してください。あなた自身の質問にコメントしないでください、あなたの質問には、追加の事実をアップデートしてください: –

+1

iは、」ページのレンダリングを保持したいので、私は最初のページをレンダリングすると、その後のアクション – rick

+0

@rickを行ういけません。 –

答えて

-1

render to responseでは、表示したいhtmlページを渡します。その他のページは、ビュー内で正しい機能をトリガするポスト(Javascriptなど)を送信する必要があります。そのビューは、次に表示される正しいページを呼び出します。

+0

ええ、それは動作しますが、私はそれが本当に可能ですわからないんだけど、サーバー側 – rick

+0

だけにそれを行うための方法がありますかしら:間違いなく、サーバ側で行うことができない/ – AlbertoPL

+0

。サーバーはクライアントが何をしているかについて何も知らないので、ページのレンダリングが完了したことを決して知らないでしょう。もちろん、単純な投稿はその問題を解決します。 – geowa4

4

長時間実行しているプロセスの場合は、2つの簡単な選択肢があります。

  1. 応答ページを送信する前にサブプロセスを生成します。

  2. "バックグラウンドサービスデーモン"を作成し、作業要求を渡します。

これはすべてDjangoの外です。 subprocessまたは他のIPCメソッドを使用して、他のプロセスと通信します。

+1

合意 - このモジュラーとウェブサーバーを中立にするために、何らかのIPCを使用したいと思います。あなたはおそらく、応答が送信された後で、Djangoの内部をハックして処理をしたくないでしょう。 – cdleary

4

これを行う一般的な方法は、メッセージキューを使用することです。キューにメッセージを配置し、ワーカースレッド(またはプロセスなど)がキューを消費し、ビューの完了後に作業を行います。

Google App Engineにはタスクキューapi http://code.google.com/appengine/docs/python/taskqueue/があり、アマゾンには単純キューサービスhttp://aws.amazon.com/sqs/があります。

クイック検索では、承認された標準のように見えるDjangoプラグインは表示されませんでした。

機能をエミュレートするには、「メッセージ」をデータベーステーブルに配置し、cronジョブで定期的にテーブルをチェックして作業を実行させることです。

http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators

だからあなたのような何かができる:

+0

+1(うまくいけば)軽量のIPCメッセージよりも効率的なアイデアです。 – cdleary

+0

Django固有のキューイングサービスhttp://code.google.com/p/django-queue-service/ – agiliq

4

は、DjangoのHttpResponseオブジェクトは、コンストラクタでイテレータを受け入れる

def myiter(): 
    yield "my content" 
    enqueue_some_task() 
    return 

def myview(request): 
    return HttpResponse(myiter()) 

イテレータの通常の使用は、読まずに、大量のデータを送信することですそれをすべてメモリに入れる。たとえば、ファイルからチャンクを読み込み、適切に処理します。私はこのように使ったことはありませんが、うまくいくようです。

+1

残念ながら、これにより、ページが完全にロードされた後でも、クライアント側でサーバーとしてロードされているように見えます最終的な結果が得られるまで接続を閉じません。 – dionyziz

2

お気に入りのソリューション:バックグラウンドタスクを処理する別のプロセスです。通常、インデックス作成や通知メールの送信などです。次に、ビューレンダリング中に、イベント処理システムにイベントを送信します( Djangoには1つが組み込まれていますが、あなたは常に1つ必要です)、そして偶数のシステムはメッセージキューにメッセージを入れます(複数のマシンや複数のバックグラウンドプロセスを持たない限りは書き込みは簡単です)問題の

10

あなたは別のスレッドを生成し、それがアクションを行うことがあります。

t = threading.Thread(target=do_my_action, args=[my_argument]) 
# We want the program to wait on this thread before shutting down. 
t.setDaemon(False) 
t.start() 

これは、あなたのDjangoの応答を送信し、最初のスレッドを終了した後も働き続けるだろう第二のスレッドで実行される「do_my_action(my_argument)」を発生します。たとえば、応答を遅らせることなく電子メールを送信することができます。

+1

シンプルで実用的なソリューション! –

+0

私はこの実装を試みました。明らかに、タスクがまだ完了していなくても、起動された2番目のスレッドは終了します。私の場合、いくつかのDBエントリを更新しています – jaysonpryde

0

おそらく、私はあなたの質問を理解していません。しかし、なぜいないような単純なもの:後方思わ

try: 
    return render_to_response() 
finally: 
    do_what_needs_to_be_done() 
+0

戻ったら、ビューは正しくレンダリングされますか?最終セクションで何が起こっているのかにかかわらず? もしそうなら、これは私が必要なものばかりです! – rick

+0

それはうまくいかないようです。最終的にコードが実行されている間、レンダリングが停止されます。 – rick

+2

最後に句があると、関数の戻り値はfinallyのコードが実行された後にのみ発生するため、意図したとおりには機能しません。 – rslite

関連する問題