エラーと修正歴・知識
ここでは卒業研究等のアプリ開発で出たエラーとその解決方法をまとめる。
卒業研究で作成するアプリの概要
これより行った実装とそのまとめを行う。
DjangoとLINEMessagingAPIを用いてオウム返しをするアプリの作成
以下のサイトを参考に、作成した。
暗記カードを作成できるようにする
「Djangoのツボとコツがゼッタイにわかる本[第2版]」を参考に作成した。
暗記カードの問題とその答えをLINEで送信する機能の追加
TypeError: Object of type Card is not JSON serializable
「bachelor/line_botproject/utils/messagecreater.py」で、「bachelor/line_botproject/card/models.py」内の「Cardクラス」をインポートし、json化することで解消した。まずは、SUBJECTの中身を呼び出して表示させた。
# 修正前の「bachelor/line_botproject/utils/messagecreater.py」 obj = Card.objects.get(pk=2) def create_single_text_message(message): if message == 'ありがとう': message = 'どういたしまして!' test_message = [ { 'type': 'text', 'text': obj } ] return test_message
# 修正後の「bachelor/line_botproject/utils/messagecreater.py」 from card.models import * import json json.dumps(SUBJECT,indent=2,ensure_ascii=False) def create_single_text_message(message): if message == 'ありがとう': message = 'どういたしまして!' test_message = [ { 'type': 'text', 'text': SUBJECT[0][1] } ] return test_message
Modelオブジェクトからjson形式に変更
LINEのメッセージとして送信するために、ModelオブジェクトをJsonに変換した。そのために実装した「bachelor/line_botproject/utils/messagecreater.py」を以下に示す。
from card.models import * import json from django.forms.models import model_to_dict def create_single_text_message(message): # Modelオブジェクトを取得 post = Card.objects.get(id=1) # ディクショナリ型に変換 post_dict = model_to_dict(post) # 辞書型からJSON型の文字列に変換 json.dumps(post_dict) test_message = [ { 'type': 'text', 'text': post_dict['question']+'\n'+post_dict['answer'] } ] return test_message
LINEメッセージに応じてカードの内容を送信する
ここではLINEメッセージを、全部の問題、全部の回答、数字、それ以外に分類して実装を行った。
まず、全部の問題、全部の回答を認識するために、以下のリストを作成した。
message_list = ["全部の問題","全部の回答"]
これにより、LINEメッセージがmessage_list[0]と等しければ「全部の問題」であり、LINEメッセージがmessage_list[1]と等しければ「全部の回答」であると判別できるようになった。ここでは、message_listの要素を追加すれば他のLINEメッセージにも対応できると考えた。
次に、メッセージが数字である場合には作成したカードのidに対応して送信するような実装を行った。LINEメッセージをint型に変換する必用があることと、送られた数字がidの範囲内であることを判別する必要があることから、以下のように実装を行った。
# オブジェクトの要素数のカウント all = Card.objects.all().count() # LINEメッセージが数字であるかどうかの判別 def isint(s): try: int(s) except ValueError: return False else: return True
これらを用いて条件式では「isint(message)==True&1<=int(message)&int(message)<=all」と記述し、送信された数字のLINEメッセージに応じたオブジェクトの内容をLINEで送信している。
次に、LINEメッセージが上記のいずれでもない場合には期待されるメッセージの例を送信するようにした。具体的には、「message_list」とオブジェクトの要素数のカウントを行った「all」をstrに変換したものを「message」に結合していき送信する。そのコードを以下に示す。
all_str = str(all) message+=":期待されないメッセージです"+'\n'+"~以下から選択してください~"+'\n' message+="1~"+all_str+"の数字"+"\n" for i in message_list: message+=i+'\n' test_message = [ { 'type': 'text', 'text': message } ] return test_message
これらの実装を踏まえ、この時点での「bachelor/line_botproject/utils/message_creater.py」を以下に示す。
from card.models import * import json from django.forms.models import model_to_dict all = Card.objects.all().count() message_list = ["全部の問題","全部の回答"] def isint(s): try: int(s) except ValueError: return False else: return True def create_single_text_message(message): if message == message_list[0]: list = [] message+=':''\n' for i in range(1,all+1): post = Card.objects.get(id=i) # ディクショナリ型に変換 post_dict = model_to_dict(post) # 辞書型からJSON型の文字列に変換 json.dumps(post_dict) list.append(post_dict['question']) message+=list[i-1]+'\n' test_message = [ { 'type': 'text', 'text': message } ] return test_message elif message == message_list[1]: list = [] message+='\n' for i in range(1,all+1): post = Card.objects.get(id=i) # ディクショナリ型に変換 post_dict = model_to_dict(post) # 辞書型からJSON型の文字列に変換 json.dumps(post_dict) list.append(post_dict['answer']) message+=list[i-1]+'\n' test_message = [ { 'type': 'text', 'text': message } ] return test_message elif isint(message)==True&1<=int(message)&int(message)<=all: message_int = int(message) # Modelオブジェクトを取得 post = Card.objects.get(id=message) # ディクショナリ型に変換 post_dict = model_to_dict(post) # 辞書型からJSON型の文字列に変換 json.dumps(post_dict) test_message = [ { 'type': 'text', 'text': post_dict['question']+'\n'+post_dict['answer'] } ] return test_message else: all_str = str(all) message+=":期待されないメッセージです"+'\n'+"~以下から選択してください~"+'\n' message+="1~"+all_str+"の数字"+"\n" for i in message_list: message+=i+'\n' test_message = [ { 'type': 'text', 'text': message } ] return test_message