【Python】FullCalendarとMySQLを連携して予定を登録できるようにする
おはようございます。
昨日に引き続き FullCalendar。
今回は MySQLにテーブルを作成してカレンダーに表示するデータを登録できるところまでやってみました。
プログラムは前回のものを流用。
スポンサーリンク
目次
下準備
MySQLのインストール
MySQL(フリーのMariaDBを使います)のインストールは次の記事を参照していただければ。
テーブルの作成
1 2 3 4 5 6 7 8 9 10 11 12 | CREATETABLEIF NOT EXISTSTBL_SCHEDULE( USER_CDVARCHAR(10) ,IDINT(10) ,TITLEVARCHAR(100) ,STARTDATETIME ,ENDDATETIME ,TEXTCOLORVARCHAR(20) ,COLORVARCHAR(20) ,URLVARCHAR(100) ,ALLDAYVARCHAR(10) ,PRIMARY KEY(USER_CD,ID) ) |
データ登録
ひとまずサンプルのデータを登録しておきます。
1 2 3 4 | DELETEFROMTBL_SCHEDULE; INSERTINTOTBL_SCHEDULEVALUES('001','1','定例会','2018-06-06T19:00:00','2018-06-06T21:00:00','','','','FALSE'); INSERTINTOTBL_SCHEDULEVALUES('001','2','外出','2018-06-18T14:00:00','2018-06-18T17:30:00','','','','FALSE'); INSERTINTOTBL_SCHEDULEVALUES('001','3','有給','2018-06-28','2018-06-28','','','','TRUE'); |
ライブラリの追加
次のライブラリを「メニュー」>「Default Settings」よりインストールします。
- mysql-connector-python-rf
画面の修正
fullCalendar のオプションで時刻の形式を指定するようにしたのと、
予定を入力した際にサーバーのメソッドを呼び出してデータ登録するようにしました。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <!DOCTYPE html> <html> <head> <title>カレンダーサンプル</title> <link rel="stylesheet"href="{{ static_url('css/fullcalendar.min.css') }}"/> <link rel="stylesheet"href="{{ static_url('css/style.css') }}"/> <script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript"src="{{ static_url('js/moment.min.js') }}"></script> <script type="text/javascript"src="{{ static_url('js/fullcalendar.min.js') }}"></script> <script type="text/javascript"src="{{ static_url('lang/ja.js') }}"></script> <script> // ページ読み込み時の処理 $(document).ready(function(){ // カレンダーの設定 $('#calendar').fullCalendar({ height:550, lang:"ja", header:{ left:'prev,next today', center:'title', right:'month,basicWeek,basicDay' }, timeFormat:'HH:mm', selectable:true, selectHelper:true, navLinks:true, eventSources:[{ url:'http://localhost:8080/getCalendar', dataType:'json', async:false, type:'GET', error:function(){ $('#script-warning').show(); } }], select:function(start,end,resource){ vartitle=prompt("予定タイトル:"); vareventData; if(title){ eventData={ title:title, start:start, end:end, allDay:true }; $('#calendar').fullCalendar('renderEvent',eventData,true); $.ajax({ url:"http://localhost:8080/regist", type:"POST", data:JSON.stringify(eventData), success:function(jsonResponse){ alert("予定を登録しました。") }, error:function(){ } }); } $('#calendar').fullCalendar('unselect'); }, editable:true, eventLimit:true, }); }); </script> </head> <body> <div id='calendar'></div> </body> </html> |
サーバープログラムの修正
新規クラス追加
MySQL用クラスを追加
MySQLUtil.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | importmysql.connector importlogging fromcontextlibimportclosing classMySQLUtil: """ MySQL 操作用クラス """ def__init__(self,host="localhost",port="3306",user="USER01",password="USER01",database="DB01"): self.config={ "host":host, "port":port, "user":user, "password":password, "database":database } self.create_db() defcreate_db(self): """ データベース、及び必要なテーブルを作成します. :return: """ withclosing(mysql.connector.connect(**self.config))asconn: c=conn.cursor() # スケジュールテーブル sql="CREATE TABLE IF NOT EXISTS TBL_SCHEDULE (" sql+=" USER_CD VARCHAR(10)" sql+=", ID VARCHAR(10)" sql+=", TITLE VARCHAR(100)" sql+=", START DATETIME" sql+=", END DATETIME" sql+=", TEXTCOLOR VARCHAR(20)" sql+=", COLOR VARCHAR(20)" sql+=", URL VARCHAR(100)" sql+=", ALLDAY VARCHAR(20)" sql+=", PRIMARY KEY(USER_CD, ID)" sql+=")" c.execute(sql) c.close() conn.commit() defdelete_data(self): """ データを削除します :return: """ logging.info("delete_data") withclosing(mysql.connector.connect(**self.config))asconn: c=conn.cursor() # データクリア sql="DELETE FROM TBL_SCHEDULE" c.execute(sql) c.close() conn.commit() definsert_data(self,data): """ データを登録します :param ticker: :return: """ withclosing(mysql.connector.connect(**self.config))asconn: c=conn.cursor() # データ登録 sql="INSERT INTO TBL_SCHEDULE VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)" c.execute(sql,data) c.close() conn.commit() defget_schedule(self,year_month,user_cd=""): """ データ(テーブル)をデータフレームに変換してかえします :return: """ result=[] withclosing(mysql.connector.connect(**self.config))asconn: c=conn.cursor(dictionary=True) sql="SELECT * FROM TBL_SCHEDULE" sql+=" WHERE (DATE_FORMAT(START, '%Y%m') = '"+year_month+"'" sql+=" OR DATE_FORMAT(END, '%Y%m') = '"+year_month+"')" ifuser_cd!="": sql+=" AND USER = '"+user_cd+"'" sql+=" ORDER BY USER_CD, ID" c.execute(sql) forrinc.fetchall(): result.append({ "user_cd":r['USER_CD'], "id":r['ID'], "title":r['TITLE'], "start":r['START'], "end":r['END'], "textColor":r['TEXTCOLOR'], "color":r['COLOR'], "url":r['URL'], "allDay":(r['ALLDAY']=='TRUE') }) returnresult defget_next_id(self,user_cd=""): """ データ(テーブル)をデータフレームに変換してかえします :return: """ result=0 withclosing(mysql.connector.connect(**self.config))asconn: c=conn.cursor(dictionary=True) sql="SELECT MAX(ID) + 1 AS ID FROM TBL_SCHEDULE WHERE USER_CD = '"+user_cd+"'" c.execute(sql) result=c.fetchone() returnresult[r"ID"] |
URLハンドラー、新規メソッドを追加
Main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | importjson importlogging importos importtornado.ioloop fromtornado.web importRequestHandler fromtornado.options importoptions fromUtils.MySQLUtil importMySQLUtil fromdatetimeimportdatetime classMainHandler(tornado.web.RequestHandler): defget(self): self.render("index.html") classGetCalendar(RequestHandler): """ カレンダー取得 """ definitialize(self): logging.info("GetCalendar [initialize]") defget(self): logging.info("GetCalendar [get]") mysql=MySQLUtil() data=mysql.get_schedule("201806","") self.write(json.dumps(data,default=support_datetime_default)) classRegistSchedule(RequestHandler): """ スケジュール登録 """ definitialize(self): logging.info("RegistSchedule [initialize]") defpost(self): logging.info("RegistSchedule [post]") mysql=MySQLUtil() param=json.loads(self.request.body) allday="TRUE"ifparam["allDay"]else"FALSE" id=mysql.get_next_id('001') data=[ "001", id, param["title"], param["start"], param["end"], "", "", "", allday ] mysql.insert_data(data) defsupport_datetime_default(o): ifisinstance(o,datetime): returno.isoformat() raiseTypeError(repr(o)+" is not JSON serializable") app=tornado.web.Application([ (r"/",MainHandler), (r"/getCalendar",GetCalendar), (r"/regist",RegistSchedule), ], template_path=os.path.join(os.getcwd(),"templates"), static_path=os.path.join(os.getcwd(),"static"), ) if__name__=="__main__": options.parse_command_line() app.listen(8080) logging.info("server started") tornado.ioloop.IOLoop.instance().start() |
起動してみる
まとめ
なかなか形になってきましたね。
次回は Bootstrap なんかを使ってもう少し詳細な予定を登録できるようにしたり、
登録済みの予定を更新、削除までできたらいいかなと思います。
ではでは。
ディスカッション
コメント一覧
まだ、コメントがありません