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

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

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

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

Python 3.x

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

Ajax

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

Q&A

解決済

Django+Ajax通信でブラウザの一部を更新しようとしたら、JSONの生データが表示される

Rio_acp
Rio_acp

総合スコア4

Django

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

Python 3.x

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

Ajax

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

1回答

0グッド

0クリップ

350閲覧

投稿2022/11/11 11:02

編集2022/11/17 02:48

前提

Djangoで、Ajax通信でページの一部を更新したいと考えています。

Ajaxでデータを送ってDjangoで処理したあとに、ページの一部(includeタグで取り込んだテンプレート)を更新したいのですが、とりあえずコンソールに送られてきたデータを表示させようと思っていました。
しかし、ブラウザには元のページではなく送られてきたJSONの生データが表示されてしまいます。
エラーがある場合はコンソールにエラーを表示させるようにしているのですが、コンソールにはエラー等は表示されません。

イメージ説明
JSONのerror:falseは、Djangoに送られたデータにバリデーションエラーがある場合にはerror:trueを表示させるようにしているため。

ブラウザにJSONデータが表示されるということは、Djangoで処理後に一応はデータを送っているのだとは思います。
表示されるJSONのデータには処理後の値が入っています。

初学者故、コード自体が拙いところが多いと思いますが、お願いいたします。

実現したいこと

  • ブラウザ上にJSONの生データを表示させないようにしたい
  • ページの一分の更新を実現させたい

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

エラーは表示されていません。
jqXHR : {"readyState":0,"status":0,"statusText":"error"}
errorThrown : undefined

該当のソースコード

models.py

1from django.db import models 2import uuid 3 4class Clients(models.Model): 5 """顧客情報""" 6 id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4) 7 8 name = models.CharField(verbose_name="名前", max_length=50, blank=False, null=False) 9 10 name_kana = models.CharField(verbose_name="ナマエ", max_length=50, blank=False, null=False) 11 12class Records(models.Model): 13 """来店情報""" 14 id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4) 15 16 client = models.ForeignKey(Clients, on_delete=models.CASCADE, related_name="related_client") 17 18 visit_date = models.DateField(verbose_name="日付", null=False, default=timezone.now) 19 20 staff = models.ForeignKey(CustomUser, null=True, on_delete=models.SET_NULL, related_name="related_records_store") 21

forms.py

1class CreateRecordFrom(forms.ModelForm): 2 class Meta(): 3 model = models.Records 4 exclude = ["client", "staff"] 5 6 def __init__(self, *args, **kwargs): 7 super().__init__(*args, **kwargs) 8 """bootstrapのclass付与""" 9 self.fields["visit_date"].widget.attrs.update({"class": "form-control", "id": "datepicker_current_record"}) 10 11class VisitedDateForm(forms.Form): 12 Visited_date = forms.CharField( 13 widget=forms.TextInput( 14 attrs={ 15 "class": "form-control col-4 mb-2", 16 "id": "txt_visitedDate", 17 "readonly": "readonly"}), 18 label="", 19 )

views.py

1class TabView(LoginRequiredMixin, generic.edit.ModelFormMixin, generic.View): 2 def get(self, request, *args, **kwargs): 3 ~省略~ 4 5 def post(self, request, *args, **kwargs): 6 if "btn_register_record" in request.POST: 7 ~省略~ 8 9 if "add_tabs" in request.POST: 10 json = {"error": True} 11 form_date = forms.VisitedDateForm(request.POST) 12 13 if not form_date.is_valid(): 14 print("Validation Error") 15 return JsonResponse(json) 16 17 json["error"] = False 18 19 # URLからPKを取得して顧客のモデルをフィルタリング 20 client_info = models.Clients.objects.get(pk=self.kwargs['pk']) 21 22 # 取得したデータを変数にし、日付をdate型に変換 23 visited_date = date.fromisoformat( 24 form_date.cleaned_data["Visited_date"]) 25 26 # 過去の来店履歴を取得 27 post_rec = models.Records.objects.select_related("client", "staff").get( 28 client__exact=client_info, visit_date__exact=visited_date) 29 30 context = {"post_record": post_rec} 31 content = render_to_string( 32 "app_records/tab_post_record.html", context, request 33 ) 34 json["content"] = content 35 36 return JsonResponse(json)

record_tab.html

1{% extends 'base.html' %} 2{% load static %} 3{% block header %} 4<!--Bootstrap、JQuery、JQueryUI、Popper、Javascript Cookie library、Javascript CSRFトークンの読み込み--> 5 ~省略~ 6{% endblock %} 7 8{% block main %} 9<!--BootstrapのタブUIを使用--> 10<!--ボタンクリックでタブを追加できるようにした--> 11 12<div class="container"> 13 <div class="card mb-3"> 14 <div> 15 <main class="p-3"> 16 <!-- BootstrapタブUI --> 17 <ul id="tab_elements" class="nav nav-tabs" role="tablist"> 18 <li class="nav-item" role="presentation"> 19 <a href="#tab_info" id="a_tab_info" class="nav-link active" role="tab" data-bs-toggle="tab" aria-selected="true">来店情報</a> 20 </li> 21 <li class="nav-item"> 22 <a href="#tab_today" id="a_tab_today" class="nav-link" role="tab" data-bs-toggle="tab" aria-selected="true">当日来店情報</a> 23 </li> 24 <li class="nav-item"> 25 <a href="#tab_today" id="a_tab_today" class="nav-link" role="tab" data-bs-toggle="tab" aria-selected="true">過去の来店情報</a> 26 </li> 27 </ul> 28 <!-- タブの中身 --> 29 <div id ="tab_contents" class="tab-content"> 30 <!--初回来店情報--> 31 <div id="tab_info" class="tab-pane active" role="tabpanel" aria-labelledby="a_tab_info"> 32 <div class="container"> 33 {% include "app_records/tab_firstvisit.html" with object=client_info %} 34 </div> 35 </div> 36 <!--当日来店情報--> 37 <div id="tab_today" class="tab-pane" role="tabpanel" aria-labelledby="a_tab_today"> 38 <div class="container"> 39 {% include "app_records/tab_record_create.html" %} 40 </div> 41 </div> 42 <!--過去の来店情報--> 43 <div id="tab_post" class="tab-pane" role="tabpanel" aria-labelledby="a_tab_post"> 44 <div class="container"> 45 {% include "app_records/tab_post_record.html" %} 46 </div> 47 </div> 48 </div> 49 </main> 50 </div> 51 </div> 52</div> 53{% endblock %} 54 55{% block js%} 56<script> 57 //DatePicker_post_recordの設定 58 //過去の来店日をDatePicker上に色付けして表示 59 ~省略~ 60 61 //過去の来店情報の参照機能 62 //日付を取得しajaxでviews.pyに送って処理する 63 //返ってきた値を参照して動的にタブを追加する(タブは5つまで追加可能) 64 $(function () { 65 $("#add_tabs").on("click", function () { 66 $.ajaxSetup({ 67 ~省略~ 68 }); 69 70 //ajaxでviewデータを送信 71 function post_date() { 72 const form_element = "#form_visitedDate"; 73 const data = new FormData( $(form_element).get(0) ) 74 const url = $(form_element ).prop("action"); 75 const method = $(form_element ).prop("method") 76 77 $.ajax({ 78 url: url, 79 type: method, 80 data: data, 81 processData: false, 82 contentType: false, 83 dataType: "json" 84 }).done(function(data) { 85 if (data.error){ 86 console.log("ERROR"); 87 } 88 else{ 89 //処理 90 //$("#content_area").html(data.content); 91 console.log(data.content) 92 } 93 }).fail( function(jqXHR, textStatus, errorThrown) { 94 console.log("ajax通信に失敗しました"); 95 console.log("jqXHR : " + JSON.stringify(jqXHR)); 96 console.log("textStatus : " + textStatus); // タイムアウト、パースエラー 97 console.log("errorThrown : " + errorThrown.message); 98 console.log("URL : " + url); 99 }); 100 }; 101 }); 102 }); 103 104</script> 105{% endblock %}

tab_firstvisit.html

1<!--初診情報と来院情報--> 2<div class="row"> 3 4 <!--左側--> 5 <div class="col"> 6 <div class="card border-0"> 7 <div class="card-body"> 8 <div class="row"> 9 <div class="col-4"> 10 <div class="form-floating mb-3"> 11 <input type="text" class="form-control" readonly="readonly" id="zip" value="{{ object.name|default:'-' }}"> 12 <label for="zip">氏名</label> 13 </div> 14 </div> 15 <div class="col-8"> 16 <div class="form-floating mb-3"> 17 <input type="text" class="form-control" readonly="readonly" id="address" value="{{ object.name_kana|default:'-' }}"> 18 <label for="address">シメイ</label> 19 </div> 20 </div> 21 </div> 22 </div> 23 </div> 24 </div> 25 26 <!--右側--> 27 <div class="col"> 28 <div class="card border-0"> 29 <div class="card-body"> 30 <div class="card border-0 mb-3"> 31 <p>来店履歴</p> 32 <div class="mb-2" id="datepicker_post_record"></div> 33 <form id="form_visitedDate" action="" method="POST"> 34 {% csrf_token %} 35 <input type="text" name="Visited_date" class="form-control col-4 mb-2" id="txt_visitedDate" readonly="readonly" required=""> 36 <!--クリックでJquery--> 37 <input class="col-4" type="submit" id="add_tabs" name="add_tabs" value="過去の来店情報を開く"> 38 </form> 39 </div> 40 </div> 41 </div> 42 </div> 43 44</div>

試したこと

恐らくページ全体の更新が入ってるのかなと考えています。
AjaxのURLが違うのかと思い、他のhtmlファイルや一応view.pyを指定してみたがダメ。

参考にしたサイト
https://noauto-nolife.com/post/django-ajax/

補足情報(FW/ツールのバージョンなど)

Python 3.9
Django 4.1

Bootstrap 5
JQuery 3.6
JQueryUi 1.13

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

0

自己解決

一応自己解決
動きはしましたが、原因が分からずじまいです。
なので、もし原因の分かる方がいらっしゃればご教授願います。

変更した点は

  • inputのクラスをsubmitからbuttonに変更
  • ajaxの処理を別の関数ベースビューで作り直す

ビューの中身自体は変更していないのですが、想定通りに動きました。

postの処理が複数あるためかと思い、一つにしてみたが動きませんでした。
submitのせいかと思いsubmitbuttonに変更したところ、Djangoからhttpレスポンスを返してないと言われました。
そのためpostメソッドの処理の問題かと思い、ドキュメントのpostのページを読んでみましたが、結局クラスベースビューではうまくいきませんでした。
クラスベースビューでAjax処理を記載したものが少なく、初学者の私には分かりませんでしたので、Ajaxをクラスベースで書くのは保留にしようと思います。

投稿2022/11/17 06:57

編集2022/11/17 06:59
Rio_acp

総合スコア4

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Django

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

Python 3.x

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

Ajax

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