2017-08-02 4 views
1

Djangoを使ってWebページのフロントエンドでスプレッドシートモデルをデプロイしようとしています。ウェブ「アプリ」の流れは単純です:xlwings + Django:接続を緩めない方法

  1. ユーザーは、Webフォーム
  2. 内のデータは、ユーザー入力を取得するには、「ru​​n_model(リクエスト)」ジャンゴバックエンドのビュー機能に
  3. 解析要求オブジェクトをフォームデータを送信入りその後、スプレッドシートの別のタブからスプレッドシート上で(sheet.range機能が使用されている)
  4. ファイル名を指定して実行「を計算()」スプレッドシートモデルと対話する
  5. 読み取り出力をxlwingsを使用してExcelモデルの入力シートに名前付き範囲を移入xlwingsと名前付き範囲を使用して(再び、sheet.range関数を使用して)。問題は、Excelのプロセスへの接続が(私はそれが別のプロセスとして、各要求を処理信じる)ジャンゴによって殺され続けているので、私はxlwings内部をインポートすることにより、(動作する最大1つの要求を得ることができるということです

ビュー機能)、2番目のリクエストを送信すると、接続が切断され、再アクティブ化されません。

は基本的に、どのように私は要求や要求ごとに、少なくとも再オープン接続の間に生きているワークブックへの接続を維持することができますか?

+0

あなたは、任意のコード例を与えることができますか? – denfromufa

+0

@denfromufa yea ...別々のプロセスを作成してしまった。私の自己投稿の答えを見てください。 – Bey

答えて

1

[OK]を、Djangoは接続を殺すの問題に対処するために、単純な「スプレッドシート・サーバ」を実施終わりました。

最初にサーバー(server.py)のコードを書いた後、コマンドラインargs(start_server.py)から起動するコードをいくつか作成し、使用する必要があるときにこのモデルへの接続を開いたviews.pyの中で)。

私は自分の(Excel + xlwings)とDjangoを独立したプロセスに分けて、インターフェイスをきれいに保ち、Djangoが私のspeadsheetモデルにどれだけアクセスできるかを制御しなければなりませんでした。今はうまく動作します。

start_server.py

""" 
Starts spreadsheet server on specified port 

Usage: python start_server.py port_number logging_filepath 
    port_number: sets server listening to localhost:<port_number> 
    logging_filepath: full path to logging file (all messages directed to this file) 
""" 

import argparse 
import os 
import subprocess 

_file_path = os.path.dirname(os.path.abspath(__file__)) 

#command line interface 
parser = argparse.ArgumentParser() 
parser.add_argument('port_number', 
help='sets server listening to localhost:<port_number>') 
    parser.add_argument('logging_filepath',help='full path to logging file (all messages directed to this file)') 
    args = parser.parse_args() 

#set up logging 
_logging_path = args.logging_filepath 
print("logging output to " + _logging_path) 
_log = open(_logging_path,'wb') 

#set up and start server 
_port = args.port_number 
print('starting Excel server...') 
subprocess.Popen(['python',_file_path + 
    '\\server.py',str(_port)],stdin=_log, stdout=_log, stderr=_log) 
print("".join(['server listening on localhost:',str(_port)])) 

server.py

""" 
Imports package that starts Excel process (using xlwings), gets interface 
to the object wrapper for the Excel model, and then serves requests to that model. 
""" 
import os 
import sys 
from multiprocessing.connection import Listener 

_file_path = os.path.dirname(os.path.abspath(__file__)) 
sys.path.append(_file_path) 
import excel_object_wrapper 

_MODEL_FILENAME = 'excel_model.xls' 
model_interface = excel_object_wrapper.get_model_interface(_file_path+"\\"+_MODEL_FILENAME) 
model_connection = model_interface['run_location'] 
close_model = model_interface['close_model'] 

_port = sys.argv[1] 
address = ('localhost', int(_port))  
listener = Listener(address) 

_alive = True 

print('starting server on ' + str(address)) 
while _alive: 
    print("listening for connections") 
    conn = listener.accept() 
    print 'connection accepted from', listener.last_accepted 

    while True: 
     try: 
      input = conn.recv() 
      print(input) 
      if not input or input=='close': 
       print('closing connection to ' + str(conn)) 
       conn.close() 
       break   
      if input == 'kill': 
       _alive = False 
       print('stopping server')        
       close_model() 
       conn.send('model closed') 
       conn.close() 
       listener.close() 
       break 
     except EOFError: 
       print('closing connection to ' + str(conn)) 
       conn.close() 
       break 
     conn.send(model_connection(*input)) 

(ジャンゴの中から)views.py

from __future__ import unicode_literals 

import os 

from multiprocessing.connection import Client 

from django.shortcuts import render 
from django.http import HttpResponse 

def run(request):  
    model_connection = Client(('localhost',6000)) #we started excel server on localhost:6000 before starting Django 
    params = request.POST 
    param_a = float(params['a']) 
    param_b = float(params['b'])   
    model_connection.send((param_a ,param_b)) 
    results = model_connection.recv() 
    return render(request,'model_app/show_results.html',context={'results':results}) 
関連する問題