目次
こんにちは。sinyです。
この記事ではDjangoでAjaxを利用する際の基本的なナレッジについてまとめました。
下図のように「いいね」ボタンを押した際にAjaxでボタン要素だけを書き換えて色を変えるという事例で解説していきます。
事前準備
まず、仮想環境とDjangoプロジェクト、アプリケーションを作成します。
python -m venv ajax Scripts\activate
Djangoをインストールしておきます。
pip install django
Djangoプロジェクトを作成します。
django-admin startproject tutorial
続いてアプリケーション作成を作成します。
python manage.py startapp post
settings.pyにアプリケーション(post)を追加します。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'post', #add ]
モデルの作成
ここでは「投稿」と「いいね」ができるモデルを作成します。
post/models.pyに以下のコードを記載します。
from django.db import models class Post(models.Model): class Meta: verbose_name =('POST') verbose_name_plural = ("POST") post_heading = models.CharField(max_length = 200) post_text = models.TextField() post_author = models.CharField(max_length = 100, default = 'anonymous') def __str__(self): return self.post_heading class Like(models.Model): class Meta: verbose_name =('Like') verbose_name_plural = ("Like") post = models.ForeignKey(Post, on_delete=models.CASCADE)
ビューの作成
post/views.pyに以下のコードを記載します。
1つ目はすべての投稿をレンダリングするIndex関数で、2つ目はいいね機能を提供するlike関数です。
from django.shortcuts import render from .models import Post, Like from django.http import HttpResponse def index(request): posts = Post.objects.all() return render(request, 'post/index.html', { 'posts': posts }) def like(request): if request.method == 'GET': post_id = request.GET['post_id'] likedpost = Post.objects.get(id = post_id ) m = Like( post=likedpost ) m.save() return HttpResponse('success') else: return HttpResponse("unsuccesful")
like関数は、いいねボタンからのAJAXリクエストを処理するために利用します。
like関数は、最初にリクエストを受け取り GETメソッドの場合は、データを読み取ります。
ここで受け取るデータは、いいね対象の投稿IDです。
Likeクラスオブジェクトを作成し、そのデータと一致するIDをデータベースに保存します。
最後に、HttpResponseを返します。
テンプレートの作成
tutorial\post\templates\postディレクトリを作成しindex.htmlを以下の通り作成します。
<!DOCTYPE html> <html> <head> <title>Like Post App</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.5.0.js" integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script> </head> <body> <div class = "display-3 color-red"><center>DataFlair AJAX Tutorial<br>Post APP</center></div> {% for post in posts %} <div class = 'container jumbotron'> <h3 class="display-5">{{ forloop.counter }}. {{ post.post_heading }}</h3> <p class="lead">{{ post.post_text }} </p> <p> <div type="text/css" class = "container">Author : {{ post.post_author }}</div> <a class="likebutton btn btn-primary btn-lg" id="like{{ post.id }}" href="#" data-catid="{{ post.id }}">Like</a> </p> <p id="message{{post.id}}"> </p> </div> {% endfor %} <script type="text/javascript"> $('.likebutton').click(function(){ var id; id = $(this).attr("data-catid"); $.ajax( { type:"GET", url: "like", data:{ post_id: id }, success: function( data ) { $( '#like'+ id ).removeClass('btn btn-primary btn-lg'); $( '#like'+ id ).addClass('btn btn-success btn-lg'); } }) }); </script> </body> </html>
このHTMLファイルには2つの重要な部分があります。
jQueryとBootstrapのインポート
jQueryはJavaScriptライブラリーであるため、本質的にサーバーの静的ファイルです。
Bootstrapや他のファイルと同じようにインポートできますが、ここではCDN経由で利用します。
リンクはjQueryの公式Webサイトにあります。
スリム版はajaxメソッドを使えないので注意。
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.5.0.js" integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>
JavaScriptからのAJAXリクエストの生成
index.htmlの最後にある<script> </ script>にAJAXを定義しています。
<script type="text/javascript"> $('.likebutton').click(function(){ var id; id = $(this).attr("data-catid"); $.ajax( { type:"GET", url: "like", data:{ post_id: id }, success: function( data ) { $( '#like'+ id ).removeClass('btn btn-primary btn-lg'); $( '#like'+ id ).addClass('btn btn-success btn-lg'); } }) }); </script>
以下のコードは、likebuttonクラスの要素がクリックされた場合にfunction()以下の処理を実行するというコードです。
$('.likebutton').click(function(){ // いいねボタンクリック時の処理を定義 var id; id = $(this).attr("data-catid"); // PostテーブルのID(post.idを)取得
id = $(this).attr("data-catid")でdata-catid="{{ post.id }}"で設定されているPOST記事のID番号を取得しています。
以下の書籍などがお勧めです。
jQueryでAjax通信の基本的な機能を提供するのが$.ajaxメソッドです。
ajaxメソッドを定義している部分が以下です。
$.ajax( { type:"GET", url: "like", data:{ post_id: id }, success: function( data ) { $( '#like'+ id ).removeClass('btn btn-primary btn-lg'); $( '#like'+ id ).addClass('btn btn-success btn-lg'); } })
ajaxメソッドにはいろんなオプションがありますが、ここでは以下を指定しています。
- type:使用するHTTPメソッド(GET | POST) ※デフォルトはGET
- url:通信先のURL
- data:送信するデータ(ハッシュ形式)
- success:通信成功時に実行するCALLBACK関数(引数は、応答データ、ステータス文字列、XMLHttpRequest)
typeにGETを指定しています。
dataにはPOSTクラスのIDを指定します。
data:{ post_id: id }
ajax通信が成功した場合は以下の関数を実行します。
success: function( data ) { $( '#like'+ id ).removeClass('btn btn-primary btn-lg'); $( '#like'+ id ).addClass('btn btn-success btn-lg'); }
関数内では以下の2つの処理を実行させます。
- id="like{{ post.id }}"に割り当てられているbtn btn-primary btn-lgクラスを削除
- id="like{{ post.id }}"に割り当てられているbtn btn-success btn-lgクラスを追加
URLの設定
post/urls.pyを新規作成し以下のコードを記載します。
from django.conf.urls import url from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('like/', views.like, name='like'), ]
プロジェクト直下のurls.pyに以下を追加します。
from django.contrib import admin from django.urls import path, include #change urlpatterns = [ path('admin/', admin.site.urls), path('ajax/', include('post.urls')), #add ]
admin.pyの設定
post/admin.py に以下の設定を追加します。
from django.contrib import admin from .models import * class PostAdmin(admin.ModelAdmin): list_display=('pk','post_heading','post_text','post_author') class LikeAdmin(admin.ModelAdmin): list_display=('pk','post') admin.site.register(Post, PostAdmin) admin.site.register(Like, LikeAdmin)
ここまできたら、一旦マイグレーションを実行します。
python manage.py makemigrations python manage.py migrate
開発サーバを起動してadminページにアクセスします。
python manage.py runserver
Postテーブルにいくつか投稿を登録したあと以下のURLにアクセスします。
以下のような非常にシンプルないいねボタン機能が付いたブログ画面が表示されます。
「いいね!」ボタンを押すと、下図の通りボタンの色が変わります。
画面全体の更新がされるのではなく、Ajaxの処理によって「いいね」ボタン部分に設定されているクラスが「btn btn-primary btn-lg→btn btn-success btn-lg」に書き換えられボタン部分だけが更新されることがわかると思います。
ちなみに、「いいね」ボタンを押すとPOSTテーブルのIDに対応するLIKEテーブルのレコードが自動的に生成されます。
このチュートリアルでは、DjangoのAJAXについて簡単に説明しました。