简体   繁体   English

Flask - 在按钮 OnClick 事件上调用 python function

[英]Flask - Calling python function on button OnClick event

I am new to python and Flask. I have a Flask Web App with a button.我是 python 和 Flask 的新手。我有一个带有按钮的 Flask Web 应用程序。 When I click on the button I would like to execute a python method not a Javascript method.当我单击按钮时,我想执行 python 方法而不是 Javascript 方法。 How can I do this?我怎样才能做到这一点?

I have seen examples with python where it redirects me to a new page using a form tag like this我看过 python 的例子,它使用这样的表单标签将我重定向到一个新页面

<form action="/newPage" method="post">

but I don't want it to redirect me to a new page.但我不希望它把我重定向到一个新页面。 I just want it to execute the python method.我只是想让它执行 python 方法。 I am making this for a Raspberry Pi robot car .我正在为 Raspberry Pi 机器人汽车做这个 When I press the forward button, I want it to run the method to Turn wheels forward.当我按下前进按钮时,我希望它运行向前转动车轮的方法。

Button HTML Code ( index.html )按钮 HTML 代码 ( index.html )

<button name="forwardBtn" onclick="move_forward()">Forward</button>

simple app.py Code - move_forward() method located here简单的 app.py 代码 - move_forward() 方法位于此处

#### App.py code

from flask import Flask, render_template, Response, request, redirect, url_for
app = Flask(__name__)

@app.route("/")
def index():
    return render_template('index.html');

def move_forward():
    #Moving forward code
    print("Moving Forward...")

I have seen similar questions to mine on Stackoverflow, but they don't seem to answer my question or I am unable to understand the answer.我在 Stackoverflow 上看到过与我类似的问题,但它们似乎没有回答我的问题,或者我无法理解答案。 If someone could please provide me a simple way to call a Python method on button click event, it would be greatly appreciated.如果有人可以给我提供一种在按钮单击事件上调用 Python 方法的简单方法,将不胜感激。

Other Questions that I have looked at:我看过的其他问题:

-- Python Flask calling functions using buttons -- Python Flask 使用按钮调用函数

-- Calling a python function with a button -- 使用按钮调用 python function

-- Flask Button run Python without refreshing page? -- Flask 按钮运行 Python 没有刷新页面?

You can simply do this with help of AJAX... Here is a example which calls a python function which prints hello without redirecting or refreshing the page.你可以在 AJAX 的帮助下简单地做到这一点......这是一个调用 python 函数的示例,该函数在不重定向或刷新页面的情况下打印 hello。

In app.py put below code segment.在 app.py 中放在代码段下面。

#rendering the HTML page which has the button
@app.route('/json')
def json():
    return render_template('json.html')

#background process happening without any refreshing
@app.route('/background_process_test')
def background_process_test():
    print ("Hello")
    return ("nothing")

And your json.html page should look like below.您的 json.html 页面应如下所示。

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type=text/javascript>
        $(function() {
          $('a#test').on('click', function(e) {
            e.preventDefault()
            $.getJSON('/background_process_test',
                function(data) {
              //do nothing
            });
            return false;
          });
        });
</script>


//button
<div class='container'>
    <h3>Test</h3>
        <form>
            <a href=# id=test><button class='btn btn-default'>Test</button></a>
        </form>

</div>

Here when you press the button Test simple in the console you can see "Hello" is displaying without any refreshing.在这里,当您按下控制台中的 Test simple 按钮时,您可以看到“Hello”正在显示而没有任何刷新。

It sounds like you want to use this web application as a remote control for your robot, and a core issue is that you won't want a page reload every time you perform an action, in which case, the last link you posted answers your problem.听起来您想将此 Web 应用程序用作机器人的远程控制,一个核心问题是您不希望每次执行操作时都重新加载页面,在这种情况下,您发布的最后一个链接会回答您的问题问题。

I think you may be misunderstanding a few things about Flask.我想你可能对 Flask 有一些误解。 For one, you can't nest multiple functions in a single route.一方面,您不能在单个路由中嵌套多个函数。 You're not making a set of functions available for a particular route, you're defining the one specific thing the server will do when that route is called.您不是在为特定路由提供一组函数,而是定义了在调用该路由时服务器将执行的特定操作。

With that in mind, you would be able to solve your problem with a page reload by changing your app.py to look more like this:考虑到这一点,您将能够通过将 app.py 更改为更像这样来解决页面重新加载的问题:

from flask import Flask, render_template, Response, request, redirect, url_for
app = Flask(__name__)

@app.route("/")
def index():
    return render_template('index.html')

@app.route("/forward/", methods=['POST'])
def move_forward():
    #Moving forward code
    forward_message = "Moving Forward..."
    return render_template('index.html', forward_message=forward_message);

Then in your html, use this:然后在你的 html 中,使用这个:

<form action="/forward/" method="post">
    <button name="forwardBtn" type="submit">Forward</button>
</form>

...To execute your moving forward code. ...执行您的前进代码。 And include this:并包括这个:

{{ forward_message }} 

... where you want the moving forward message to appear on your template. ...您希望前进消息出现在模板上的位置。

This will cause your page to reload, which is inevitable without using AJAX and Javascript.这将导致您的页面重新加载,这在不使用 AJAX 和 Javascript 的情况下是不可避免的。

最简单的解决方案

<button type="button" onclick="window.location.href='{{ url_for( 'move_forward') }}';">Forward</button>

index.html (index.html should be in templates folder) index.html(index.html 应该在模板文件夹中)

<!doctype html>
<html>

<head>
    <title>The jQuery Example</title>

    <h2>jQuery-AJAX in FLASK. Execute function on button click</h2>  

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"> </script>
    <script type=text/javascript> $(function() { $("#mybutton").click(function (event) { $.getJSON('/SomeFunction', { },
    function(data) { }); return false; }); }); </script> 
</head>

<body>        
        <input type = "button" id = "mybutton" value = "Click Here" />
</body>    

</html>

test.py测试文件

from flask import Flask, jsonify, render_template, request
app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')

@app.route('/SomeFunction')
def SomeFunction():
    print('In SomeFunction')
    return "Nothing"



if __name__ == '__main__':
   app.run()


PYTHON PYTHON
you can create a generic route to execute everything you want in python :你可以创建一个通用路由来执行你想要的一切python

@app.route('/<FUNCTION>')
def command(FUNCTION=None):
    exec(FUNCTION.replace("<br>", "\n"))
    return ""

JAVASCRIPT JAVASCRIPT
now you create a javascript function to access the python function:现在你创建一个javascript function 来访问python function:

// pythonCommand can be any code in python
function ExecPythonCommand(pythonCommand){
    var request = new XMLHttpRequest()
    request.open("GET", "/" + pythonCommand, true)
    request.send()
}

ONCLICK ONCLICK
and finally call the javascript function in onclick and say what do you want execute in python script:最后在 onclick 中调用javascript onclick并说出你想在python脚本中执行什么:

<button type="button" onclick="ExecPythonCommand('move_forward()')">i'm a button</button>

now its working!现在它的工作! but we has some problems for example if try onclick="ExecPythonCommand('print('Hi!')')" because has much quotation marks, so you can create some javascript function to execute anything you want, this can be do like this:但是我们有一些问题,例如如果尝试onclick="ExecPythonCommand('print('Hi!')')"因为有很多引号,所以你可以创建一些 javascript function 来执行你想要的任何东西,这可以这样做:

// function created before
function ExecPythonCommand(pythonCommand){
    var request = new XMLHttpRequest()
    request.open("GET", "/" + pythonCommand, true)
    request.send()
}


// function to print Hi!
function PrintHi(){
    ExecPythonCommand("print('Hi!')") 
}


// function to print hour
function PrintHour(){
    ExecPythonCommand("import datetime as dt<br>print(dt.datetime.now().hour)")
    // in python script you was need import datatime as dt or pass all in the
    // function, for example ExecPythonCommand("import datetime as dt<br>print(dt.datetime.now().hour)")
    // and use <br> to break line (in python script i'm was converting to normal \n, using \n here has not working)
}


// function to do anything
function FunctionName(){
    ExecPythonCommand("some command") 
}

...

and call the function you want in onclick并在 onclick 中拨打您想要的onclick

basically exec() executes a string as a line of code基本上exec()将字符串作为一行代码执行

the order of process basically is onclick -> javascriptFunction -> pythonFunction进程的顺序基本上是onclick -> javascriptFunction -> pythonFunction

Just put this at the end of your function把这个放在你的 function 的末尾

return '', 204

The HTTP 204 No Content success status response code indicates that a request has succeeded, but that the client doesn't need to navigate away from its current page. HTTP 204 No Content 成功状态响应代码表示请求已成功,但客户端不需要离开其当前页面。https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204

Found it in this question: Python Flask Intentional Empty Response在这个问题中找到它: Python Flask Intentional Empty Response

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM