テンプレートhtmlがdbのカラムの値を出力しない
listでデータを保持していたため出力されなかった。
下記がlistでデータを保持したままrender_htmlにデータを渡していたソース。
# -*- coding: utf-8 -*- from flask import Flask, render_template import psycopg2 app = Flask(__name__) @app.route('/') def hello(): users = 'USERNAME' db = 'DABATABASE' password = 'PASSWORD' conn = psycopg2.connect(" user=" + users + " dbname=" + db + " password=" + password) cur = conn.cursor() cur.execute('select * from menu;') results = cur.fetchall() cur.close() conn.close() return render_template('dnselect.html', menues=results) if __name__ == "__main__": app.run(host='0.0.0.0')
テンプレートhtml
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>HTMLFILE reading</title> </head> <body> <h1>Flask tutorial</h1> {% for menu in menues %} <p>name:{{menu.name}} price:{{menu.price}} yen</p> {% endfor %} </body> </html>
これだとname:とpticeとyenしか出なかったのでprint文で元のファイルを少し弄ってデータの中身を確認することにした。
# -*- coding: utf-8 -*- import psycopg2 def hello(): users = 'USERNAME' db = 'DATABASE' password = 'PASSWORD' conn = psycopg2.connect(" user=" + users + " dbname=" + db + " password=" + password) cur = conn.cursor() cur.execute('select * from menu;') results = cur.fetchall() cur.close() conn.close() print(results) if __name__ == "__main__": hello()
結果を見てみるとlistでデータを保持していた。
$ python test_list.py [(1, '\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x93', 400, 400), (2, ' \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x932', 300, 300), (3, ' \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x933', 200, 200), (4, ' \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x934', 100, 100), (5, ' \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x935', 50, 50)]
これはどうするかと検索していたら同じことで悩んでいた人がその人のブログを参考にした。
https://qiita.com/itoufo/items/7306122497fd4f712bff
ブログのように書き換えたprintモジュールを作成して起動させてみた。
import psycopg2 import psycopg2.extras def dcit_smp(): users = 'USERNAME' db = 'DATABASE' password = 'PASSWORD' conn = psycopg2.connect(" user=" + users + " dbname=" + db + " password=" + password) cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) cur.execute('select * from menu;') results = cur.fetchall() dict_result = [] for row in results: dict_result.append(dict(row)) cur.close() conn.close() print(dict_result) if __name__ == "__main__": dcit_smp()
辞書型に変形されていた。
[{'price': 400, 'calorie': 400, 'name': '\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x93', 'id': 1}, {'price': 300, 'calorie': 300, 'name': ' \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x932', 'id': 2}, {'price': 200, 'calorie': 200, 'name': ' \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x933', 'id': 3}, {'price': 100, 'calorie': 100, 'name': ' \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x934', 'id': 4}, {'price': 50, 'calorie': 50, 'name': ' \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe5\xbc\x81\xe5\xbd\x935', 'id': 5}]
あとはモジュールを作り変えていく。
# -*- coding: utf-8 -*- from flask import Flask, render_template import psycopg2 import psycopg2.extras app = Flask(__name__) @app.route('/') def hello(): users = 'USERNAME' db = 'DATABASE' password = 'PASSWORD' conn = psycopg2.connect(" user=" + users + " dbname=" + db + " password=" + password) cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) cur.execute('select * from menu;') results = cur.fetchall() dict_result = [] for row in results: dict_result.append(dict(row)) cur.close() conn.close() return render_template('dnselect.html', menues=dict_result) if __name__ == "__main__": app.run(host='0.0.0.0')
これで起動してみたら無事動かなかった。
エラーがまた出てきてしまった。
ASCII対策
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128)
上記なようなエラーが出てたので調査してみた。
検索したら割と簡単に出てきた。
https://qiita.com/jack-low/items/91bf9b5342965352cbeb
うまいことモジュールに盛り込んでみた。
# -*- coding: utf-8 -*- from flask import Flask, render_template import psycopg2 import psycopg2.extras import sys, codecs app = Flask(__name__) reload(sys) sys.setdefaultencoding('utf-8') @app.route('/') def hello(): users = 'USERNAME' db = 'DATABASE' password = 'PASSWORD' conn = psycopg2.connect(" user=" + users + " dbname=" + db + " password=" + password) cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) cur.execute('select * from menu;') results = cur.fetchall() dict_result = [] for row in results: dict_result.append(dict(row)) cur.close() conn.close() return render_template('dnselect.html', menues=dict_result) if __name__ == "__main__": app.run(host='0.0.0.0')
起動してみたところうまく日本語に変換されていて必要な値が取ることができた。