7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Electron + React + Django REST Framework でlocal GUI アプリを作る

Posted at

Electron+react+django REST framework

Local GUIアプリを作成する必要が出た際、言語の候補としては C#,python,Java などが上がってくることと思います。ただし、GUIの見た目がほぼWindows95時代のアプリのごとくいけていない。。。
そこでFrontをreactで、BackendをDjangoRESTFramework で実装しElectronを使ってdesktop app 化することにしました。
情報が少なく、苦労したので、個人メモがわりに残しておきます。

参考にさせていただいたサイト:
① [Wijmo(ウィジモ)」とElectron、Reactを組み合わせて、Web技術でデスクトップアプリをつくろう] (https://codezine.jp/article/detail/13182)
Reactアプリから Django Rest API を叩いてみる

方針:

  1. 最初にElectron+React でLocal GUI アプリを作成する(上記①)
  2. 次にDjango REST Framework を導入してAPIのend point を作成する(上記②)
  3. electron 起動時にpython-shell を使って、django server を立ち上げる
  4. フロントからhttp通信を使ってデータを取得する

方針1、2

基本的には①のサイトの流れに沿ってreact,electron のGUIアプリを作成していきます。
上記サイトに沿って作成すれば問題なく作成できると思いますし、コードを無断転載するのもよくないと思い詳細は載せません。
react+electron でGUIアプリが起動することが確認できたら、そこに②のサイトを参考にしながらDjango REST framework を導入します。

こちらも基本的に②のサイトに沿ってDjangoREST framework を導入していきます。
最終的なファイル構造は以下のようになっているはずです。

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

#3 electron 起動時にpython-shell を使って、django server を立ち上げる
この時点でDjangoAPIの作成ができており、electron+react のアプリもできている状態です。
ここから問題となったのは
electronを立ち上げる際にどうやって同時にdjango serverを立ち上げて、electron が終了する際にdjango serverも終了するか
でした。
djangoのlocal server さえ立ち上げてしまえば、後はFront からaxiosなどでAPIを叩くだけです。
方針としては、electron.js の中でpython-shell を使って command python manage.py runserver localhost:8000を叩けば良いのですが、その方法がわからず苦労しました。
結論といたしまして、まず上記のelectron.js の中で

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 process をkill するためにGlobal変数にプロセスを格納しておきます。)
python manage.py だけではサーバーは起動しません。 この後にrunserver を繋げたいのですが、、、、その方法がどうしてもわからず(ご存知の方は教えて下さい!)、結局 manage.py file にある関数execute_from_command_line(sys.argv) のsys.argvのところに直接"runserver"を入れることで解決しました。

manage.py
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 server も立ち上がるはずです。
最後にelectron を終了したときに同時にdjango server も閉じるように以下を書き加えます。

public/electron.js
//終了時に子プロセスとその子孫を終了させる
app.on("quit", () => {
  // ここを追加!!
  // pythonShellをkill
  subpy.childProcess.kill('SIGINT');
  
  pids.forEach((pid) => {
    try {
      process.kill(pid);
    } catch (e) {
      console.log(e);
    }
  });
});

4 front からHttp通信でデータを取得

3のプロセスが終われば、あとはフロントからAPI通信でデータを取得するだけです。

App.tsx
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 を使った記事はいくつか拝見させてもらったのですが、djangoREST framework を使った記事は少なくて苦労したので、どなたかの参考になれば幸いです。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?