【问题标题】:Django how to make a button that first runs js function and then function in .pyDjango如何制作一个首先运行js函数然后在.py中运行的按钮
【发布时间】:2021-10-04 10:20:33
【问题描述】:

我正在构建一个 Django 应用程序,在我的一个 HTML 表单上,我有一个按钮,应该首先运行一个 js 函数(ocr()),然后在 .py 中运行另一个函数。

我已经尝试了this 帖子的第一个解决方案。现在它运行 javascript 函数,但它不会继续运行 .py 中的函数。

更新: 我添加了 onsubmit 事件,该函数现在返回 true。但是还是不行。

这是js脚本:

<div>
        
        <script>
            var ocr = function(event){
                event.preventDefault();

                Tesseract.recognize(
                    document.getElementById('imgde').src,
                    'deu',
                    { logger: m => console.log(m) }
                ).then(({ data: {text}}) => {
                    console.log(text);
                    document.getElementById('txt_voc_de').innerHTML = ['<input type="hidden" name="txt_voc_de" id="txt_voc_de" value="',text, '"/>'].join('');
                })

                Tesseract.recognize(
                    document.getElementById('imgen').src,
                    'eng',
                    { logger: m => console.log(m) }
                ).then(({ data: {text}}) => {
                    console.log(text);
                    document.getElementById('txt_voc_en').innerHTML = ['<input type="hidden" name="txt_voc_en" id="txt_voc_en" value="',text, '"/>'].join('');
                })
                
                
   
                
            };

            var form = document.getElementById("imgForm");
            form.addEventListener("submit", ocr, true);
        </script>
        <input type="submit" onsubmit="ocr();" id="senden" class="inputfiles" />
        <button for="senden" class="button" id="weiter_btn" >WEITER</button>
        {% csrf_token %}
        </div>

更新 2:

我现在正在尝试向 JS 函数中的 URL 发送请求,并让它被视图拾取。但它只返回之前的 html 表单。

这是更新后的脚本:

<div>
        
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
            $(document).ready(function () {
                $("#imgForm").submit(function (event) {
                    event.preventDefault();
                    $.ajax({
                    type: "POST",
                    beforeSend: function() {
                        Tesseract.recognize(
                            document.getElementById('imgde').src,
                            'deu',
                            { logger: m => console.log(m) }
                        ).then(({ data: {text}}) => {
                            console.log(text);
                            document.getElementById('txt_voc_de').innerHTML = ['<input type="hidden" name="txt_voc_de" id="txt_voc_de" value="',text, '"/>'].join('');
                        })

                        Tesseract.recognize(
                            document.getElementById('imgen').src,
                            'eng',
                            { logger: m => console.log(m) }
                        ).then(({ data: {text}}) => {
                            console.log(text);
                            document.getElementById('txt_voc_en').innerHTML = ['<input type="hidden" name="txt_voc_en" id="txt_voc_en" value="',text, '"/>'].join('');
                        })
                    } ,
                    url: "/upload/",
                    success: function () {
                        $('#message').html("<h2>Contact Form Submitted!</h2>")
                    }
                    });
                    return false;
                });
                });
            
        </script>
       <input type="submit" id="senden" class="inputfiles"/>
       <button for="senden" class="button" id="weiter_btn" >WEITER</button>
        {% csrf_token %}
        </div>

问题可能是 beforesend 函数在 javascript 中,对吗? 但是有没有办法可以在 ajax 请求之前在 javascript 中运行该函数?

这是我在views.py中的函数

def upload(request):
    if request.is_ajax():
        message = "Yes"
        txt_voc_en = request.POST.get("txt_voc_en")
        txt_voc_de = request.POST.get("txt_voc_de")
        print(txt_voc_de)
        print(txt_voc_en)

        vocsde = ocr_core(txt_voc_de)
        vocsen = ocr_core(txt_voc_en)
        
        messages.success(request, vocsde, extra_tags="de")
        messages.success(request, vocsen, extra_tags="en")
        context = {'vocsen': vocsen,
                    'vocsde': vocsde}
        return render(request, 'success.html', context)
     else:
        message = "Not ajax"
     return HttpResponse(message)



【问题讨论】:

    标签: javascript html django ajax


    【解决方案1】:

    根据您的问题,您首先希望通过 JavaScript 处理一些表单数据,将结果嵌入到隐藏的输入类型中。最后,您希望将这些隐藏输入的数据发送到 views.py 以进行进一步处理。在更新的脚本中,您将 javascript 与 AJAX 混合在一起。您可以按如下方式更新您的脚本 -

    <script>
        var ocr = function(event) {
            event.preventDefault();
    
            Tesseract.recognize(
                document.getElementById('imgde').src,
                'deu', {
                    logger: m => console.log(m)
                }
            ).then(({
                data: {
                    text
                }
            }) => {
                console.log(text);
                Tesseract2(text);
            })
        };
    
    function Tesseract2(text_de) {
        Tesseract.recognize(
            document.getElementById('imgen').src,
            'eng', {
                logger: m => console.log(m)
            }
        ).then(({
            data: {
                text
            }
        }) => {
            console.log(text);
            AjaxCall(text_de, text);
        })
    
    }
    
    function AjaxCall(text_de, text_en) {
        $.ajax({
            type: 'POST',
            url: "/upload/",
            data: {
                csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(), // to avois csrf error
                txt_voc_en: text_en,
                txt_voc_de: text_de
            },
            success: function(json) {
                //Do whatever you want
            },
            error: function(xhr, errmsg, err) {
                console.log(xhr.status + ": " + xhr.responseText);
            }
        });
    }
    
    var form = document.getElementById("imgForm");
    form.addEventListener("submit", ocr, true);
    </script>
    

    此代码将首先通过 javascript 进行预处理,然后通过 AJAX 将其发送到 views.py,并带有必需的参数“txt_voc_en”和“txt_voc_de”。

    【讨论】:

    • 谢谢!唯一的问题是它在 ajax 调用之后运行 Tesseract 部分。所以“txt_voc_en”和“txt_voc_de”的值还是空的。有没有办法将 Tesseract 部分放在 beforeSend 函数中?
    • 由于 Tesseract.recognize() 不能立即执行(这是一个耗时的过程),它只是返回 promise 并让其旁边的代码在完成该过程时执行。即使 beforesend 也不是 promise 感知的,所以在使用 beforesend 时也会发生同样的事情。
    • 一种可能的解决方案是将 AJAX 调用包装在另一个函数中,并在第二个 Tesseract.recognize() 的 .then() 块结束时调用该函数(您在其中放置了 console.log(文本))。还为 2 个 tesseract 调用创建 2 个单独的函数,并从第一个 .then() 块调用第二个 tesseract.recognize()。
    • 谢谢!现在可以了。但是当 "txt_voc_en" 和 "txt_voc_de" 在 vi​​ews.py 函数中打印时,它是空的。而且我认为原因可能是html表中开头为“”的值更新得不够快。你知道我如何将文本值从 tesseract 函数直接传递给 ajax 调用,而不使用 html 中的输入标签吗?
    • 虽然我不太确定为什么值仍然是空的。但是,如果您想将这些文本值传递给 Ajax 调用,而不将其存储在输入标记中,您可以通过将这些值作为函数参数传递来实现。我已经更新了我的答案。
    【解决方案2】:

    您可以向 JS 函数中的 URL 发送请求,并让视图获取它。

    This post should help you

    【讨论】:

    • 我应该把ajax请求放在哪里? js函数结束?
    • 我不太熟悉 AJAX,但您可能希望将当前函数包装在 AJAX 方法中。显然,如果你想使用$.ajax 语法,你必须将你当前的 JS 代码迁移到 jQuery。
    猜你喜欢
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    相关资源
    最近更新 更多