Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9309

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

$
0
0
Electron+react+django REST framework Local GUIアプリを作成する必要が出た際、言語の候補としては C#,python,Java などが上がってくることと思います。ただし、GUIの見た目がほぼWindows95時代のアプリのごとくいけていない。。。 そこでFrontをreactで、BackendをDjangoRESTFramework で実装しElectronを使ってdesktop app 化することにしました。 情報が少なく、苦労したので、個人メモがわりに残しておきます。 参考にさせていただいたサイト: ① Wijmo(ウィジモ)」とElectron、Reactを組み合わせて、Web技術でデスクトップアプリをつくろう ② 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 を使った記事は少なくて苦労したので、どなたかの参考になれば幸いです。

Viewing all articles
Browse latest Browse all 9309

Trending Articles