質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

1611閲覧

pythonから返す値をJSON形式でレスポンスしたい

hakuryuu

総合スコア2

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2022/01/28 02:15

開発環境

windows10
python 3.7.9
Django 2.2.2
PostgreSQL 10.18

解決したいこと

Djangoでアプリケーションを作っているのですが、Ajaxを使っていてpythonで返す値を最後Json形式に変換してから画面上にレスポンスを返したいです。

発生している問題・エラー

画面上にレスポンス返せても文字化けを起こしてしまう。
具体的には英語、数字は問題なく表示できるが日本語が文字化けしてしまう。UTF-8でコーディングしているのに"U3042"みたいな感じでUnicode形式になってしまう。

[{"model": "library.book", "pk": "3893814317", "fields": {"book_register_date": "2022-01-14T10:48:19", "book_author": "\u3042\u3060\u3061\u305f\u304f\u3084", "book_title": "test2", "book_sub_title": "test2", "book_sample_path": "test2", "book_publisher": "\u8db3\u7acb", "book_page_num": 1000, "book_genre": "A", "book_symbol": "A", "book_num": "A", "book_isbn_num": "1234567890128", "book_lend_count": 1, "book_sample_count": 1, "book_delete_flg": false, "book_lend_flg": false}}]

というように一部文字化けしてしまう

該当するソースコード

view.py

python

1class LendView(generic.ListView, models.Model): 2 template_name = "lend.html" 3 paginate_by = 5 4 model = Book 5 6 def scandisp(req): 7 #カメラのプログラムを呼び出しています 8 scandata = write_data.kasidasi() 9 # 受け取ったデータをhtmlに渡す。 10 11 for list in scandata: 12 data2 = Book.objects.filter(book_isbn_num = list) 13 data3 = data2.only() 14 15 #serializeでjson形式に変換 16 data_list = serializers.serialize("json", data3) 17 #最後にレスポンス 18 return JsonResponse(data_list, safe=False)

HTML部分

html

1<body> 2 <span>文字を入力した後にボタンを押してください</span> 3 <br> 4 <button type="button" id="lend" onclick="clickBtn()">貸出</button> 5 <br> 6 <span id="text"> 7 </span> 8

javascript

1<script> 2 function clickBtn() { 3 var txt = document.getElementById("lend").value; 4 5 $.ajax({ 6 url: "{% url 'library:scandisp' %}", 7 method: 'GET', 8 data: {"input_data": txt}, 9 dataType: "json", 10 contentType: "application/json", 11 beforeSend: function(xhr, settings) { 12 if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 13 xhr.setRequestHeader("X-CSRFToken", csrf_token); 14 } 15 }, 16 error: function(xhr, status, error) { 17 console.log("error") 18 } 19 }) 20 .done(function(data) { 21 var aaa = document.getElementById("text").textContent = data; 22 var bbb = encodeURIComponent(aaa); 23 document.getElementById('text2').innerText = bbb; 24 console.log("text2"); 25 }); 26 27 // csrf_tokenの取得に使う 28 function getCookie(name) { 29 var cookieValue = null; 30 if (document.cookie && document.cookie !== '') { 31 var cookies = document.cookie.split(';'); 32 for (var i = 0; i < cookies.length; i++) { 33 var cookie = jQuery.trim(cookies[i]); 34 // Does this cookie string begin with the name we want? 35 if (cookie.substring(0, name.length + 1) === (name + '=')) { 36 cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 37 break; 38 } 39 } 40 } 41 return cookieValue; 42 } 43 44 // ヘッダにcsrf_tokenを付与する関数 45 function csrfSafeMethod(method) { 46 // these HTTP methods do not require CSRF protection 47 return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 48 }; 49 } 50 51</script>

自分で試したこと

python側でJSONへ変換する処理を変得てみたのですが、

data_list = serializers.serialize("json", data3) ↓ data_list = json.dumps(data3, ensure_ascii=False, encoding='utf8', indent=2) AttributeError: type object '' has no attribute 'abstract

とエラーが出てしまい解決せず。
scriptタグの中でエンコード方式を指定しても解決しませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

UTF-8でコーディングしているのに"U3042"みたいな感じでUnicode形式になってしまう。
"book_author": "\u3042\u3060\u3061\u305f\u304f\u3084"

それは Unicode Escape Sequence (UES) の結果だと思います。

UES というのは \uxxxx という形で表される Unicode 文字で、xxxx はその文字の Unicode コードになります。UES となる理由はシリアライザでエスケープ処理が行われているからで、フレームワークがそういう仕様になっているからだと思います。


追記

ちなみに ASP.NET Core MVC (Core v3.1 以降)ではデフォルトで UES が適用されます。興味があれば以下の記事を見てください。

ASP.NET Core MVC の Unicode Escape Sequence (UES)
http://surferonwww.info/BlogEngine/post/2020/03/11/aspnet-core-mvc-controller-json-method-replaces-non-ascii-characters-with-5cuxxxx.aspx


追記2

下のコメントに、

そのままデシリアライズしてエンコード前の文字列を取得できるはずで、UES を外す必要はないと思いますけど?

と書きましたけど具体的にどうなるかを以下にに追記しておきます。

下の画像を見てください。JavaScript のコードの変数 json に代入したのは質問にある JSON 文字列そのものです。日本語の部分はエスケープされたままになってます。それを JSON.parse で JavaScript オブジェクト(連想配列)にデシリアライズすると "book_author": "\u3042\u3060\u3061\u305f\u304f\u3084" はエスケープが解除されて画像の赤枠で囲ったように "あだちたくや" となっているのが分かりますか?

イメージ説明

質問の JavaScript のコードにある、

.done(function(data)

の data には、ajax での要求の結果期待通り JSON 文字列の応答が返ってきていれば、それをデシリアライズした JavaScript オブジェクト(画像のコードで言うと deserialised)が渡されているはずですので確認してみてください。

投稿2022/01/28 02:22

編集2022/01/28 05:17
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hakuryuu

2022/01/28 03:03

リンク先の記事も読ませていただきました。 フレームワークの仕様でこうなるとのことですが、リンク先のサンプルコードでエンコード方式を変えることができるという認識で合っていますでしょうか?
退会済みユーザー

退会済みユーザー

2022/01/28 04:35

> リンク先のサンプルコードでエンコード方式を変えることができるという認識で合っていますでしょうか? ASP.NET Core MVC の話ですので質問者さんのケース(Python ですか?)でどのようにできるかは自分は分かりません。 元々エンコードするのはセキュリティ対策だそうで、そのままデシリアライズしてエンコード前の文字列を取得できるはずで、UES を外す必要はないと思いますけど? (どうしても読めないとダメだとかのわからずやの客がいるとかなら話は別ですけど)
退会済みユーザー

退会済みユーザー

2022/01/28 05:02

上のコメントに、 > そのままデシリアライズしてエンコード前の文字列を取得できるはずで、UES を外す必要はないと思いますけど? と書きましたけど具体的にどうなるかを回答欄に追記しておきます。
hakuryuu

2022/01/28 06:15

とても分かりやすい回答ありがとうございました!
guest

0

普通にfetchで受ければ普通に表示されます

javacript

1fetch('sample.json').then(res=>res.json()).then(console.log);

javascript

1<script> 2window.addEventListener('DOMContentLoaded', ()=>{ 3 btn.addEventListener('click',async()=>{ 4 const params={txt:document.querySelector('#lend').value}; 5 const url='views.py?'+Object.entries(params).map(x=>x.map(encodeURIComponent).join('=')).join('&'); 6 const data=await fetch(url).then(res=>res.json()); 7 text.textContent=JSON.stringify(data); 8 }); 9}); 10</script> 11<input id="lend" value="てすと"> 12<span>文字を入力した後にボタンを押してください</span> 13<button type="button" id="btn">貸出</button> 14<span id="text"></span> 15<span id="text2"></span> 16

投稿2022/01/28 02:19

編集2022/01/28 04:20
yambejp

総合スコア114779

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hakuryuu

2022/01/28 02:58

javascriptをあまり触らないため書き方をよく理解していないのですが、書き方は .done(function(data) { document.getElementById("text").textContent = data; fetch('').then(res=>res.json()).then(console.log); で合っていますでしょうか? またfetch('')の中の相対パスはデータの送り主先(今回だとviews.pyというファイルからデータが送られてきています)のファイルを指定するので合ってますしょうか?
yambejp

2022/01/28 04:21 編集

受け取ったjsonデータはオブジェクトなのでtextContentには表示できないと思います 命題ではlendのvalueをパラメータで渡す記述になっていますが、 lendってボタンですよね?なにかがおかしいと思います
hakuryuu

2022/01/28 04:36

なるほど。試行錯誤してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問