概要
質問フォームから入力したデータをバックエンドのPythonに送信して受け取る。
受け取ったデータはDBに格納するなど。
質問は複数あり、同様に回答も複数ある。
結論
辞書型の取り出しには、get(),getlist()を使う
コード
1.フロントから入力したデータを送信
const url = 'https://xxxxxx.xxx/regist'
const params = new FormData();
params.append("id", this.id);
params.append("category", this.category);
for(let i=0;i<this.questions.length;i++){
params.append("question", this.questions[i]);
params.append("answers", this.answers[i]);
}
const headers = {
accept: "application/json",
"Content-Type": "multipart/form-data",
Authorization: `Bearer ` + API_TOKEN
};
const response = await axios.post(url, params, { headers: headers })
if(response.status == '200'){
// 成功した時の処理
}
else{
// 失敗した時の処理
}
補足
for(let i=0;i<this.questions.length;i++){
params.append("question", this.questions[i]);
params.append("answers", this.answers[i]);
}
appendで値を追加した場合、既存のキーが存在する場合には値のセットに新しい値を追加します。
その為、一つのキーに複数の要素を含めることができます。
逆に、同じキーが存在する場合に上書きしたい場合は、set()を利用すると上書きされます。
params.set("question", this.questions[i]);
2.バックエンド側のPythonで受信
(確認として出力のみ)
class lineQuestionnaireApi(APIView):
def post(self, request, format=None):
print(request.data)
question_data = request.data
print(question_data['id'])
print(question_data['category'])
print(question_data['question'])
print(question_data['answers'])
実行結果
<QueryDict: {
'id': ['abc123'],
'category': ['2'],
'question': ['好きな色?', '好きな食べ物?', '好きな数字?', '好きな季節?'],
'answers': ['青', 'いちご', '7', '春']
}>
abc123 #id
2 #category
好きな季節? #question
# 質問の最後のみしか出力されていない
# 期待していた結果→['好きな色?', '好きな食べ物?', '好きな数字?', '好きな季節?']
春 #answers
# 回答の最後のみしか出力されていない
# 期待していた結果→['青', 'いちご', '7', '春']
疑問
questionとanswersの値が最後の要素だけしか出力されない
おさらい
リスト型
要素の書き換え可
index番号で要素にアクセス
list_data = ['a', 'b', 'c', 'd']
print(list_data[0])
### a
タプル型
要素の書き換え不可
index番号で要素にアクセス
tuple_data = ('a', 'b', 'c', 'd')
print(list_data[0])
### a
辞書型
要素の書き換え不可
キー(文字列や数値)で要素にアクセス
dict_data = {'い':'a', 'ろ':'b', 'は':'c', 'に':'d'}
print(list_data['い'])
### a
試したこと
受け取ったデータ型を確認してみる
question_data = request.data
print(type(question_data))
<class 'django.http.request.QueryDict'>
QueryDict型になっている。
辞書型の拡張ということらしい。
辞書型の値の取り出し
DjangoのQueryDictには同じキーの中にある複数の値をlistとして取り出せるメソッドがある。
それが、getlist
ということで、getlistを使って値を取り出す。
user_id = questionnaire_data.get('user_id', default=None)
category = questionnaire_data.get('category', default=None)
question_list = questionnaire_data.getlist('question', default=None)
answers_list = questionnaire_data.getlist('answers', default=None)
リスト型以外は以下でも値は取得できるが、辞書型オブジェクトから取得する場合はget()メソッドを使う
user_id = questionnaire_data['user_id']
辞書型オブジェクト.get(key, default=None)
(keyが存在しなかった場合にNoneを返す)
print(question_list)
# ['好きな色?', '好きな食べ物?', '好きな数字?', '好きな季節?']
list型として取り出すことに成功。
リスト型からインデックスと要素取得して順番に取り出す
続いて、リストの値を順番に取り出す。
今回は、質問と回答をセットで取り出したいので、共通となるインデックス番号をキーとする。
インデックスと要素を取得したいので、
enumerate関数を利用。
print(user_id)
print(category)
for key,value in enumerate(question_list):
print(question_list[key])
print(answers_list[key])
出力結果
abc123 #id
2 #category
# ----- 以下はfor文で出力した内容 -----
好きな色? #question[0]
青 #answers[0]
好きな食べ物? #question[1]
いちご #answers[1]
好きな数字? #question[2]
7 #answers[2]
好きな季節? #question[3]
春 #answers[3]
想定していた結果を得ることができました。
所感
pythonでよく使うリストと辞書型の理解があいまいのままだった点と
フロントから受け取ったデータ型の理解が漏れていた点が悩んだ理由。