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

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

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

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

2374閲覧

Djangoでjsファイルを分割するとエラーになる

yukoishii

総合スコア16

Django

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

1クリップ

投稿2020/03/24 04:48

編集2020/03/25 17:01

前提・実現したいこと

Djangoを使ってWebアプリを作成しています。
htmlファイルの中にjqueryを書いて動かしていたんですが、すっきりさせたかったのでstaticディレクトリへ分割したところエラーになりました。

発生している問題・エラーメッセージ

もともとはこれで正常に動いていました。

views

1def good_add(request): 2 post_pk = request.POST.get('post_pk') 3 user = request.user 4 post = Post.objects.get(pk=post_pk) 5 good_of_user = Good.objects.filter(target=post, user=user) 6 post_good_count = post.good_set.count() 7 if good_of_user.exists(): 8 good_of_user.delete() 9 post_good_count -= 1 10 else: 11 post_good_count = post.good_set.count() 12 good = Good(target=post, user=user) 13 good.save() 14 post_good_count += 1 15 if post.is_good is None: 16 post.is_good = False 17 post.save() 18 d = { 19 'good_message': 'ありがとう', 20 'good_count': post_good_count, 21 } 22 return JsonResponse(d)

html

1 <h2>高評価</h2> 2 <div id="good_count"> 3 <p>{{ object.good_set.count }}</p> 4 </div> 5 6 <hr> 7 8 <h2>高評価の追加</h2> 9 <form id="good_add" action="{% url 'note:good_add' %}" method="POST"> 10 <input type="hidden" id="id_title" value={{ object.pk }}> 11 <button type="submit">送信</button> 12 {% csrf_token %} 13 </form> 14 15<script> 16const getCookie = name =>{ 17 if (document.cookie && document.cookie !== '') { 18 for (const cookie of document.cookie.split(';')){ 19 const [key, value] = cookie.trim().split('='); 20 if(key === name) { 21 return decodeURIComponent(value); 22 } 23 } 24 } 25}; 26const csrftoken = getCookie('csrftoken'); 27 28document.getElementById('good_add').addEventListener('submit', e => { 29 e.preventDefault(); 30 31 const url = '{% url "note:good_add" %}'; //ここに処理させるビューのURL 32 const postArea = document.getElementById('good_count'); 33 const title = encodeURIComponent(document.getElementById('id_title').value); 34 fetch(url, { 35 method: 'POST', 36 body: `post_pk=${title}`, 37 headers: { 38 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 39 'X-CSRFToken': csrftoken, 40 }, 41 }).then(response => { 42 return response.json(); 43 }).then(response => { 44 $('#good_count').empty(); 45 const p = $('<p>', {text: response.good_count}); 46 $('#good_count').append(p); 47 }).catch(error => { 48 console.log(error); 49 }); 50}); 51</script>

しかし、このスクリプトタグ内のコードだけを static/js/push_button.js として

<script src="{% static 'js/push_button.js' %}"></script>

としたところ、

DoesNotExist at /note/good_add/

Post matching query does not exist.

となってしまいました。

試したこと

staticファイルはしっかり参照できていると思います。
なにぶん、jQueryを習いたてなのでエラーの対処法がわかりません。
ご教授よろしくお願いします。

##追記

views

1def good_add(request): 2 post_pk = request.POST.get('post_pk') 3 post = Post.objects.get(pk=post_pk) 4 user = request.user 5 if Good.objects.filter(user=user, target=post).exists(): 6 good = Good.objects.get(user=user, target=post) 7 good.delete() 8 else: 9 Good.objects.create(target=post, user=user) 10 if post.is_good is None: 11 post.is_good = False 12 post.save() 13 good_counts = Good.objects.filter(target=post).count() 14 d = { 15 'good_counts': good_counts, 16 } 17 return JsonResponse(d)

html

1 <h2>高評価</h2> 2 <div id="good_count"> 3 <p>{{ object.good_set.count }}</p> 4 </div> 5 <br> 6 <h2>Goodの追加</h2> 7 <form id="good_add" action="{% url 'note:good_add' %}" method="POST"> 8 <input type="hidden" id="post_id_for_good" value={{ object.pk }}> 9 <button type="submit">送信</button> 10 {% csrf_token %} 11 </form> 12 13<script src="{% static 'js/push_good.js' %}"></script>

push_good

1const getCookie = name =>{ 2 if (document.cookie && document.cookie !== '') { 3 for (const cookie of document.cookie.split(';')){ 4 const [key, value] = cookie.trim().split('='); 5 if(key === name) { 6 return decodeURIComponent(value); 7 } 8 } 9 } 10}; 11const csrftoken = getCookie('csrftoken'); 12 13document.getElementById('good_add').addEventListener('submit', e => { 14 e.preventDefault(); 15 16 const url = document.getElementById('good_add').action; 17 const post_id = encodeURIComponent(document.getElementById('post_id_for_good').value); 18 fetch(url, { 19 method: 'POST', 20 body: `post_pk=${post_id}`, 21 headers: { 22 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 23 'X-CSRFToken': csrftoken, 24 }, 25 }).then(response => { 26 return response.json(); 27 }).then(response => { 28 $('#good_count').empty(); 29 const p = $('<p>', {text: response.good_counts}); 30 $('#good_count').append(p); 31 }).catch(error => { 32 console.log(error); 33 }); 34});

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

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

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

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

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

guest

回答1

0

ベストアンサー

html

1const url = '{% url "note:good_add" %}'

この部分で落ちていると思われます。
{% ... %}はdjangoテンプレートのタグのため、djangoから呼び出したテンプレート内では反映されますが

html

1<script src="{% static 'js/push_button.js' %}"></script>

で呼び出したjsファイルは該当のタグは使えないようになっています。

urlの値はformのactionと同じものを取得したいと思われますので、

document.getElementById('good_add').action

あたりでactionの値を取得するといいかもしれません。

投稿2020/03/24 06:36

netsuy

総合スコア170

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

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

yukoishii

2020/03/24 07:30

回答ありがとうございます。 エラーメッセージの意味がわかりました、postを得るためのパラメータが適切ではないということだったんですね。 しかし回答の通りに試してみたのですが、残念ながら解決できませんでした。 url = document.getElementById('good_add').action としたり、 url = encodeURIComponent(document.getElementById('good_add').action) としてみたのですがうまくいきません。 この取得の仕方は間違えてるんでしょうか?
netsuy

2020/03/24 07:57

大変失礼いたしました。 同じエラーがまだ出ていらっしゃるということでしょうか? jsファイルに移す前は正常に動いていたということは、PostやGoodsのテーブルにはデータが入っているのは間違いないのですよね? 1度確認をお願いしたいのですが、 urlとtitleをalertあたりでよいので、ボタン押下後にしっかり値が取得されていますでしょうか?
yukoishii

2020/03/25 00:06

お手数おかけしてこちらこそすみません。 確認してみたところurlとuserは取得できていましたが、titleがnullとなっていました。 const title = encodeURIComponent(document.getElementById('id_title').value); となぜかencodeしていたところが原因かと思いましたが、document.getElementById('id_title').value;のみにしても動きません。
netsuy

2020/03/25 01:20 編集

確認なのですが、 <p>{{ object.good_set.count }}</p> や  value={{ object.pk }} には そもそも値は正常に反映されてらっしゃいますでしょうか? もし未反映であればobject.pkをしっかり返すようにviewを直さなければなりません。 現状のエラーはnullになっていることが原因だと思われますので、 もしvalueが反映されているのであれば気になった部分があって直してもらいたいのですが、 <input type="hidden" id="id_title" value={{ object.pk }}> ↓ <input type="hidden" id="id_title" value="{{ object.pk }}"> に直して再度アラート出してみてもらってもいいでしょうか?
yukoishii

2020/03/25 04:41

指摘された点を変更して様々なことを試してみたところ、アラートでは表示されますがpostは取得できませんでした。fetchで渡すところが間違えているのでしょうか?
yukoishii

2020/03/25 09:22

どうやらview内の1行目 post_pk = request.POST.get('post_pk') ここでうまく取得できてなさそうです
netsuy

2020/03/25 10:01 編集

csrftokenはアラートで値は表示されますか? また、print(request.POST)の結果を教えていただきたいです。 https://gist.github.com/marteinn/3785ff3c1a3745ae955c こちら近しい内容っぽいのですが、関係あるかわかりませんが setting.pyの修正(すでにしていたらすみません)と、fetch内に「credentials: "same-origin",」を追加するとどうなりますか?
yukoishii

2020/03/25 11:44

print(request.POST)の値をみて試行錯誤した結果、ようやく解決できました!!! netsuyさんのおかげです、こんなにも面倒見ていただき本当にありがとうございました!!!
netsuy

2020/03/25 12:18

良かったです! 後学のため、問題点をお教えいただいてもいいでしょうか?
yukoishii

2020/03/25 17:06

追記としてコードを載せました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問