2017-07-12 7 views
0

私はあなたの助けが必要です。私の見解では、イメージのサイズに応じて時間がかかるbashプロセスを実行します。処理中は、ロード中のGIF画像と文章を表示したい(「お待ちください、画像が処理されています」など)。私はテンプレートでそれをやろうとしましたが、処理中ではなくスクリプトの実行終了時にレンダリングされます。 誰かが私を助けることができますか?私は似たような質問 "Django - show loading message during long processing"を見つけましたが、答えはあまり明確ではありませんでした。Django - bashプロセスの実行中にイメージを表示する

これは私の図である。処理の最後に表示され

def process(request): 
    var = Image.objects.order_by('id').last() 
    subprocess.call("./step1.sh %s" % (str(var)), shell=True) 
    subprocess.call("./step2.sh %s" % (str(var)), shell=True) 
    return render(request, 'endexecut.html') 

テンプレート: "endexecut.html"

{% extends 'base.html' %} 
{% block content %} 
<div class="container"> 
    <div class="row"> 
    <div class="jumbotron"> 
     <div class="row"> 
      <center> 
       <p> Your image is processed succesfully ! </p> 
      </center> 
      </div> 
    </div> 
</div> 

{%の末端ブロック%}

+0

webappにこのように動作させる場合、ajaxを回避する方法はありません。だからあなたはその技術に精通しているべきです。 – Jingo

答えて

1

あなたのベストショットはajaxを使用することです。

def process(request): 
    return render(request, "endexecut.html") 

使いたいどんなテキストで、デフォルトでは、あなたのendexecutテンプレートのGIF画像を表示します。あなたは、単にあなたのビューを書き換えることができます。テンプレートページのスクリプトセクションで

は、あなたは、このようなAJAX呼び出しを持つことができます。

$.ajax({ 
     url: '/some-app/some-view/', 
     type: 'GET', 
     dataType: 'json', 
     success: function(result){ 
       $('#image-id').attr('src', result.image); 
     }, 
     error: function(xhr){ 
       alert(xhr.responseText); //Remove this when all is fine. 
     } 
}); 

Ajaxが(あなたがurl.pyで定義されているはずです)のURLを指しています、 urlはあなたの長いbash処理を行うビューを指しています:

def bash_processing(request): 
     # Do your bash processing here 
     return JsonResponse({'image': 'image url here'}) 

これはうまくいくはずです。 ただし、処理に時間がかかる場合は、celeryを使用してバックグラウンドで処理することを検討してください。

+0

あなたの答えをありがとう、あなたが言ったajaxセクションにjs構文を追加する必要がありますか?私のjavascriptブロックで、または単にの間で使用しますか? –

+0

スクリプトセクション間で使用してください。 さらに、私はそのコードを間違えてしまい、修正しました。 ajaxコードの 'dataType'は' 'json''ではなく' 'ajax''でなければなりません –

+0

これはうまくいかず、同じ問題があり、何も表示せずに処理し、最後にjson応答を表示します:image: "https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif" –

0

Iは同じ問題があり、jqueryとajaxcallを使用しました。こうすることで、アップロードを開始したときにgifを表示し、終了したらgifを削除することができます。

+0

コードやチュートリアルを持っていますか?私はこれに固執していますか? –

+0

https://stackoverflow.com/questions/13465711/how-do-i-post-with-jquery-ajax-in-djangoここでは、どのように動作するかを確認します。1 - GIFを表示し、残りを隠す2 - GIFを隠し残りを表示する3 - ajax成功関数 – Jbertrand

1

Celeryを参照すると、ジョブを作成して監視することができます。これにより、process(request)が置き換えられます。独自のprocess(request)を使用すると、それを自分で実装しなければならないでしょうし、それに対するソリューションがすでに存在するのであれば、なぜそうするのでしょうか?

実行中のサブプロセスの状態は、ブラウザ(AJAX)からのJSを使用して、このように照会することができます。プロセスをトリガーするビューで

def task_progress_json(request, job_id): 
    """ 
    A view to report the progress to the user 
    :param job_id: 
    :param request: 
    """ 
    job = AsyncResult(job_id) 
    data = job.result or job.state 
    if job.state == states.FAILURE or isinstance(data, Exception): 
     data = {'failure': "{}: {}".format(_('Error'), data)} 
     if job_id in request.session: 
      request.session[job_id] = None 
    else: 
     # see http://docs.celeryproject.org/en/latest/reference/celery.states.html#std:state-PROPAGATE_STATES 
     # and http://docs.celeryproject.org/en/latest/getting-started/next-steps.html#calling-tasks 
     if data == states.PENDING: 
      last_state = request.session.get(job_id, None) 
      if last_state == states.PENDING: 
       data = {'failure': "Error: No Job Running"} 
       request.session[job_id] = None 
      else: 
       request.session[job_id] = data 
     if isinstance(data, dict): 
      next_url = data.pop('next_url', None) 
      next_kwargs = data.pop('next_kwargs', {}) 
      if next_url: 
       data['next_url'] = reverse(next_url, kwargs=next_kwargs) 
    return HttpResponse(json.dumps(data), content_type='application/json') 

、例えば、ユーザがのSubmitボタンをクリックしたときフォームを起動すると、ジョブを開始します。

def form_valid(self, form): 
    # this is just an example, implement as you like 
    fs = FileSystemStorage(location=settings.IMAGE_ROOT) 
    stored_file = fs.save(form.cleaned_data['file'].name, form.cleaned_data['file']) 
    job = import_imag_task.delay(stored_file, self.request.user.id, self.spectre.id) 
    # this is another view that shows the progress bar 
    # the process of the progress bar is displayed according to 
    # results fetched from the above task_progress_json request via AJAX 
    return HttpResponseRedirect(reverse('import_image_progress') + '?job=' + job.id) 
関連する問題