DjangoでAjax入門

スポンサードリンク



こんにちは。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の基礎知識がないと理解できないと思いますので、良くわからない人はまずはjQueryの基礎を勉強しましょう。

以下の書籍などがお勧めです。

 

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メソッドにはいろんなオプションがありますが、ここでは以下を指定しています。

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つの処理を実行させます。

  1. id="like{{ post.id }}"に割り当てられているbtn btn-primary btn-lgクラスを削除
  2. 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にアクセスします。

http://127.0.0.1:8000/ajax/

以下のような非常にシンプルないいねボタン機能が付いたブログ画面が表示されます。

 

いいね!」ボタンを押すと、下図の通りボタンの色が変わります。

画面全体の更新がされるのではなく、Ajaxの処理によって「いいね」ボタン部分に設定されているクラスが「btn btn-primary btn-lg→btn btn-success btn-lg」に書き換えられボタン部分だけが更新されることがわかると思います。

 

ちなみに、「いいね」ボタンを押すとPOSTテーブルのIDに対応するLIKEテーブルのレコードが自動的に生成されます。

このチュートリアルでは、DjangoのAJAXについて簡単に説明しました。

 

 

おすすめの記事