【Django】Ajax 入門|JavaScript fetch + JsonResponse で非同期通信の実装パターン

スポンサードリンク



Django · Ajax · 非同期通信入門

同期通信(Ajax)は、ページ全体を再読み込みせずに一部の情報だけサーバーから取得・更新する仕組みです。Django でも JavaScript の fetch + 専用のビュー(JsonResponse) を使えば、検索のサジェスト・無限スクロール・モーダル送信など、現代的な UX を実装できます。本記事では Django + Ajax の基本パターンを、サンプルコード付きで一通り体験する入門解説です。

この記事ではDjangoでAjaxを利用する際の基本的なナレッジについてまとめました。

下図のように「いいね」ボタンを押した際にAjaxでボタン要素だけを書き換えて色を変えるという事例で解説していきます。

 

user@sinyblog:~/article 01_section_1.md事前準備

まず、仮想環境とDjangoプロジェクト、アプリケーションを作成します。

python


python -m venv ajax

Scripts\activate

 

Djangoをインストールしておきます。

python


pip install django

 

Djangoプロジェクトを作成します。

python


django-admin startproject tutorial

 

続いてアプリケーション作成を作成します。

python


python manage.py startapp post

 

settings.pyにアプリケーション(post)を追加します。

python


INSTALLED_APPS = [

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'post',  #add

]

 

user@sinyblog:~/article 02_section_2.mdモデルの作成

ここでは「投稿」と「いいね」ができるモデルを作成します。

post/models.pyに以下のコードを記載します。

python


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)



  

 

user@sinyblog:~/article 03_section_3.mdビューの作成

post/views.pyに以下のコードを記載します。

1つ目はすべての投稿をレンダリングするIndex関数で、2つ目はいいね機能を提供するlike関数です。

python


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を返します。

 

user@sinyblog:~/article 04_section_4.mdテンプレートの作成

tutorial\post\templates\postディレクトリを作成しindex.htmlを以下の通り作成します。

default


<!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メソッドを使えないので注意。

 

default


<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を定義しています。

default


<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()以下の処理を実行するというコードです。

default


    $('.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の基礎を勉強しましょう。

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

created by Rinker
¥3,168 (2026/05/01 20:31:51時点 楽天市場調べ-詳細)

 

jQueryでAjax通信の基本的な機能を提供するのが$.ajaxメソッドです。

ajaxメソッドを定義している部分が以下です。

default


        $.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通信が成功した場合は以下の関数を実行します。

default


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を新規作成し以下のコードを記載します。

python


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に以下を追加します。

python


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 に以下の設定を追加します。

python


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


python manage.py makemigrations

python manage.py migrate

 

開発サーバを起動してadminページにアクセスします。

python


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について簡単に説明しました。

 

 

おすすめの記事