Django:带状态视图的POST表单(ajax?) [英] Django: POST form with status view (ajax?)

查看:42
本文介绍了Django:带状态视图的POST表单(ajax?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表单,需要一些用户输入,将其发布到视图中,进行一些计算,然后重定向到输出.

I have a form which takes some user input, posts to a view, does some calculations and then redirects to the output.

在运行计算时,我可以在浏览器选项卡中看到小轮子在旋转,但是用户必须等待时才坐在那里查看表单.

While the calculations are running I can see the little wheel spinning in my browser tab, but the user has to look at their form just sitting there while they wait.

我想进行各种状态查看,其中在某些部分进行计算时,它会向用户显示有关其进度的消息,例如在过程的第3部分",完成后,将重定向到结果.

I would like to make a status view of sorts, where while the calculations are underway at certain parts it shows the user a message regarding its progress e.g. "at part 3 of the process", and when it is done then redirects to the results.

所以我要有人帮助我.

例如在 views.py

def form(request):
    if request.method == 'POST'
    form = MyForm(request.POST)
        if form.is_valid():
             form = convert_form_to_model(form.cleaned_data, MyModel)
             # DO calculations
             send_message_to_user_waiting_screen('Part One Complete')
             # DO more calculations
             send_message_to_user_waiting_screen('Part two Complete')
             ....
             return HttpResponseRedirect(reverse('my_app:results', args(form.id,)))
        else:
            return render(request, 'my_app/form.html')
    else:
        form = MyForm()
        render(request, 'my_app/form.html')

推荐答案

我已经给您足够的入门知识,但是您将不得不自己学习一些jquery和javascript来处理从轮询中获取的消息.没那么糟糕;您可以在堆栈溢出和整个Internet上使用大量示例.希望这会有所帮助.

I've given you enough to get started, but you will have to learn some jquery and javascript on your own to handle the messages you're getting from polling. It's not that bad; there are numerous examples you can use on stack overflow and all over the internet. Hope this helps.

添加到模型:

class UserCalculationUpdate(models.Model)
    user = models.ForeignKey(User)
    stage = models.SmallIntegerField(default=0, max_length=1)
    message = models.TextField(default='')

    _stage_dict = {-1: 'Failed.', 0: 'On stage 1 of 3', 1: 'On stage 2 of 3', 
                    2: 'On stage 3 of 3', 3: 'Calculation Complete!'}

    def get_stage(self):
        return self._stage_dict[self.stage]

运行 python manage.py makemigrations ,调试我犯的任何错误,然后运行 python manage.py migration .

run python manage.py makemigrations, debug any mistakes I've made, and run python manage.py migrate.

导入您的新模型和json内容并编辑您的 view :

import your new model and json stuff and edit your view:

from django.http import JsonResponse

from my_app.models import UserCalculationUpdate 

# I'd rename your view to something else.
def form(request):
    if request.method == 'POST'
    form = MyForm(request.POST)
        if form.is_valid():
            form = convert_form_to_model(form.cleaned_data, MyModel)
             """
             looks to see if there is a UserCalculationUpdate object 
             corresponding to the present user. If not, it creates one
             and sets obj.stage = 0 and sets created = True, otherwise, 
             it sets obj.stage = 0 for the object already in the db 
             and sets created = False
             """
            obj, created = UserCalculationUpdate.objects \
                .update_or_create(user=request.user, 
                                  defaults={'stage':0}) 
            result1, success, message = step_one_calc(form)
            # storing the progress in our new model, success should be
            # a boolean
            if success:
                obj.update(stage=1)
            else obj.update(stage=-1, message=message)
                return HttpResponse() # whatever you want to happen when fails
            result2, success, message = step_two_calc(result1, success)
            if success: 
                obj.update(stage=2)
            else obj.update(stage=-1, 
                            message=message)
                return HttpResponse() # whatever you want to happen when fails
            """
            . . . and so on . . .
            """ 
            return HttpResponseRedirect(reverse('my_app:results', args(form.id,)))
        else:
            return render(request, 'my_app/form.html')
    else:
        form = MyForm()
        render(request, 'my_app/form.html')

def poll_view(request):
    user_calc_update = UserCalculationUpdate.objects \
        .filter(user=request.user):
    if len(user_calc_update) != 0:
        stage_message = user_calc_update[0].get_stage()
        results_message = user_calc_update[0].message
        # 0 is incomplete 1 is complete
        completion_status = 0 if user_calc_update[0].stage == 3 else 1
        return JsonResponse({
            'message': f'{stage_message} {results_message}',
            'completion_status': completion_status
        })  

    except UserCalculationUpdate.DoesNotExist:
        return JsonResponse({
            'message': 'Beginning Calculations',
            'completion_status': 0
        })  

添加到您的 urls :

url(r'^calculation_poll/$', view.poll_view, name='poll_view')

确保在模板顶部添加 {%load url%}
通过包含< script src ="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 来添加jquery如果您还没有,请在标题中添加该脚本,然后将该脚本添加到模板中的某个位置:

make sure to add {% load url %} to the top of your template,
add jquery by including <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> in your header if you haven't already, and add this script someonwhere in your template:

<script>
    // $('#id') is the jquery selector syntax for selecting an element by its id
    // and manipulating it.
    $('#calc_submit_button_id').click(function(){ //adding an onclick trigger
        $('#loading').show(); //the 'loading' element is where you want your                      //information about your progress to show, this can
                              // a modal or a bootstrap alert or whatever you like.
                              // the .show() method removes any 'display:none' or
                              // 'display: hidden' from the style of the 'loading'
                              // element.
        pollingFunction = $.ajax({
            dataType: "json",
            url:"{% url "poll_view" %}",
            data: '',
            success: function (message){
                /* use console.log() and look at the console using inspect element
                (ctrl +  shift + i in chrome, right click + Q in firefox) to 
                examine the structure of your message
                */
                console.log(message)
                # Some code that decides what to do with message
                if (you wish to display the message and poll again)
                {   
                    //adds message to ('#loading'), should make it prettier, but
                    //serves our purpose for now
                    ('#loading').empty()
                    ('#loading').html('<h3>' + JSON.stringify(message) + '</h3>')
                    //wait ten seconds, poll again
                    setTimeout(pollingFunction, 10000)
                }
                else(you wish to end polling and hide the ('#loading') element)
                {
                    $('#loading').hide();
                }
            },
            error: function(jqXHR){
                console.log(jqXHR)
                ('#loading').html('<h3>Oh no, something awful happened, better check the logs.</h3>')
            }
        });
    });
</script>

这篇关于Django:带状态视图的POST表单(ajax?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆