使用 Electron + React + Django REST Framework 来制作本地GUI应用程序

电子 + React + Django REST框架

当需要创建本地GUI应用时,可能会考虑的语言选项包括C#,Python,Java等。然而,GUI的外观几乎与Windows95时代的应用程序一样糟糕…
所以我们决定使用React作为前端,使用Django REST Framework作为后端,使用Electron来将其转化为桌面应用程序。
由于信息有限,我们遇到了一些困难,所以我将其记录下来作为个人备忘。

以下是我参考的网站:
1. 使用Wijmo(ウィジモ)和Electron、React来制作Web技术的桌面应用程序
2. 尝试从React应用程序调用Django Rest API

方针:
1. 首先使用Electron+React创建本地GUI应用(上述①)。
2. 然后引入Django REST Framework创建API的终点(上述②)。
3. 在Electron启动时使用python-shell来启动Django服务器。
4. 通过HTTP通信从前端获取数据。

方針1和方針2

基本上,我們將按照①網站的流程來創建react和electron的GUI應用程序。如果按照上述網站進行創建,我認為應該可以順利完成,而且我認為未經許可轉載代碼也是不好的,所以不會提供詳細內容。一旦確認使用react+electron啟動GUI應用程序是可行的,我們將參考②網站並引入Django REST framework。

我们也基本上将按照第2个网站的指导来引入DjangoREST框架。
最终的文件结构应该如下所示。

react-electron-django
|
|- django
|     |- db.sqlite3
|     |- manage.py
|     |- djangoMain
|     |_ djangoApp
|-- frontend
|     |-public
|     |  |-electron.js
|     |  |- preload.js
|     |-src
|        |-App.tsx
         |-index  

使用 Python Shell 在启动时启动 Django 服务器。

在这一阶段,DjangoAPI已经创建好了,同时electron+react的应用程序也已经完成。
问题出在如何同时启动django server和electron,并在electron结束时关闭django server。
一旦django的本地服务器启动,只需要通过axios等方法从前端调用API即可。
作为方针,只要在electron.js中使用python-shell命令 `python manage.py runserver localhost:8000`即可,但是我对这种方法感到困惑和困扰。
最终的结论是,在上述的electron.js文件中,首先要

//pythonShell のプロセスを後でkill するためにglobal 変数を設けている
let subpy;
//アプリケーションが起動可能になったらcreateWindowを呼び出す
app.on("ready", () => {
  createWindow()

  // Django 側のサーバーを立てるコマンド
  subpy=PythonShell.run(`${path.join(__dirname, "../../django/manage.py")}`, null, function (err, result) {  // exe:'./resources/app/app.py'    edit: './app.py'
    if (err) throw err;
    console.log(result);
  });
});

执行python manage.py命令。
(在关闭electron时,为了杀死django进程,将进程存储在全局变量中。)
只有python manage.py不会启动服务器。我想要在这之后连接runserver,但是…我怎么也找不到方法(知道的人请告诉我!),最终我通过直接在manage.py文件的execute_from_command_line(sys.argv)函数的sys.argv处加入”runserver”来解决了问题。

def main():
    """Run administrative tasks."""
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangotodo.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc

    # execute_from_command_line(sys.argv)
    //書き換えたところ
    execute_from_command_line(['',"runserver"])


if __name__ == '__main__':
    main()

当我启动electron时,django服务器应该同时启动。
最后,我将添加以下内容以在关闭electron时同时关闭django服务器。

//終了時に子プロセスとその子孫を終了させる
app.on("quit", () => {
  // ここを追加!!
  // pythonShellをkill
  subpy.childProcess.kill('SIGINT');

  pids.forEach((pid) => {
    try {
      process.kill(pid);
    } catch (e) {
      console.log(e);
    }
  });
});

通过Http通信从4个前端获取数据。

当完成第三个步骤后,只需通过前端进行API通信来获取数据。

import axios from "axios";
import React, {useState} from "react"

function App() {
  const [message, setMessage] = useState("top secret")

  const sendMessage = async ()=>{
    const returnMessage = await axios.get('http://localhost:8000/api/').then((res)=>{
      return res.data
    })
    setMessage(returnMessage)
  }
  return (
    <div>
      <button onClick={sendMessage}>
        テストメッセージ送信
      </button>
      <h1>
        {message}
      </h1>
    </div>
  );
}

export default App;

最后

我看了一些使用React、Electron和Flask的文章,但使用Django REST框架的文章很少,我很困扰,希望能对某些人有所帮助。

bannerAds