Django:QuerySetのJSON変換で大ハマリした件
- 2021.03.30
- Python備忘録
- API, Backend, Django, Frontend, JavaScript, python, SPA, Vue.js, エラー改善, スクリプト備忘録
Django:QuerySetのJSON変換で大ハマリした件
解決した形は一番シンプルだったというオチが付いた今回のドはまり事件。
キカッケはFrontとBackに分けたDjango構築でのBack側のAPI出力です。
1 |
<span class="str">"WorkList"</span><span class="pun">:</span> <span class="str">"[{\"model\": \"managedcontents.operation\", \"pk\": 9, \"fields\": {\"customer\": 1, \"title\": \"ほげほげ\", ...</span> |
QuerySetとして抽出された値をフロントで受け取れるようにAPIを設置したのですが、上のようなコードが生成されました。で、これを展開して何とかしてやろうと思ったのですがフロント側でKeyごとの値を取得しようとしても出来ない…。
原因と解決方法
上の様に『\”model¥”』といった姿になる場合は1レコードの文字列としてAPI送信されています。
この原因はjson.dumpの動作です。
Front側で展開できる姿は下の形で送信される必要があります。
1 2 3 4 5 6 |
{ "WorkList": [ { "id": 9, "customer_id": 1, "title": "ほげほげ", |
QuerySetの場合、この形にするのは非常に簡単で1行スクリプトで完了です。
1 2 3 |
WorkLists = hoge.objects.filter(customer__exact=userid).order_by('-enddate') json_encode = list(WorkLists.values()) |
間違えの元凶は難しく考えてしまうから
そうなんですよね。
グーグル先生にこんなキーワードを入れてみます。
「Django QuerySet JSON 変換」
これで出てくる先人の記事は多くの場合でこんなコードが書いてあります。
1 |
json_encode = serializers.serialize('json', WorkList, ensure_ascii=False) |
1 |
json_encode = json.dumps(list(WorkList), cls=DjangoJSONEncoder) |
で、これを行うと一番最初に記載した状態になると。
リスト(配列)やDataFrameをFrontで使いたい時どうすればいい?
配列(リスト)にして送信すればOKです。下のような姿になるので Vueであれば v-forなどが利用できます。
今回の件で色々とテストしてみましたが、json.dumpsを行うとリストやDataFrameの先頭/末尾に【”】が入り大きな文字列と化してしまうようです。う~ん、これは環境差なのでしょうか。
FrontEndで展開する値をBackEndからAPIで送信する構造を作りたい訳なので、APIでKey取得できる環境でデータを渡せれば問題ありません。そんな時は配列を格納してreturn Response で渡しましょう。
1 2 3 4 5 6 7 8 9 10 11 |
works = [] d1 = [1,'test_title01','test_image01'] d2 = [12,'test_title02','test_image02'] works.append(d1) works.append(d2) params = { 'WorkList': works } return Response(params) |
まとめ
なんかこの辺の情報ってGoogle先生の抽出する回答も迷走しているようです。
例えば、JSON化の目的がグラフなのであればJson.dumpsした下の姿でも展開できます。
1 2 3 |
<span class="pun">{</span> <span class="str">"WorkList"</span><span class="pun">:</span> <span class="str">"[[1, \"test_title01\", \"test_image01\"], [12, \"test_title02\", \"test_image02\"]]"</span> <span class="pun">}</span> |
つまり、この姿で困るのは多くの場合でWEB側での表示になるかと思います。
でもね、Google先生そこら辺の情報をあまり出してくれないんですよね。
情報としては、Replaceで強引に【 \”test_title01\”】を【 “test_title01”】に変換して先頭と末尾の【”】を削除しようというものまでありましたが、それは多分できたとしても正しい回答ではないような気がします。
私の様に出会った情報を先頭から順に実験していくと多くの時間を消費してしまいます。
目的がWEB側での表示であればリスト化して渡すのが一番簡単です。
-
前の記事
Vue+Pug:JavaScriptで作成した変数をPugで読込もうとしたが出来ないらしい 2021.03.26
-
次の記事
JavaScript:お手伝いしているプログラミングスクールで聞かれた質問【let/var/constの違い】 2021.04.04
コメントを残す