<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ajax | リューブログ</title>
	<atom:link href="https://ryuusan.com/tag/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>https://ryuusan.com</link>
	<description>就活生だった時の気づきや日常の発信のほか、技術ブログとしても運用しています。</description>
	<lastBuildDate>Wed, 14 Oct 2020 04:57:14 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://ryuusan.com/wp-content/uploads/2020/03/cropped-logo-32x32.png</url>
	<title>Ajax | リューブログ</title>
	<link>https://ryuusan.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>DjangoでAjaxを使っていいねボタンを作る</title>
		<link>https://ryuusan.com/django-ajax/</link>
					<comments>https://ryuusan.com/django-ajax/#respond</comments>
		
		<dc:creator><![CDATA[リューさん]]></dc:creator>
		<pubDate>Wed, 14 Oct 2020 04:56:15 +0000</pubDate>
				<category><![CDATA[プログラミング学習]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Django]]></category>
		<guid isPermaLink="false">https://ryuusan.com/?p=353</guid>

					<description><![CDATA[こんにちは。リューさん(@Ryu_programs)です。今回の記事ではjQueryを使ってDjangoでAjaxを行っていきたいと思います。 この記事ではDjangoについては詳細な説明をしていないので、Djangoの [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>こんにちは。リューさん(<a href="https://twitter.com/Ryu_programs">@Ryu_programs</a>)です。今回の記事ではjQueryを使ってDjangoでAjaxを行っていきたいと思います。</p>



<p class="wp-block-paragraph">この記事ではDjangoについては詳細な説明をしていないので、Djangoの実装方法などについては以下の記事を読んでみてください。</p>



<a href="https://ryuusan.com/django3/" title="Djangoで簡単な「文字カウントメモ」を作ってみる" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img decoding="async" width="160" height="90" src="https://ryuusan.com/wp-content/uploads/2020/03/Django-160x90.jpg" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://ryuusan.com/wp-content/uploads/2020/03/Django-160x90.jpg 160w, https://ryuusan.com/wp-content/uploads/2020/03/Django-120x68.jpg 120w, https://ryuusan.com/wp-content/uploads/2020/03/Django-320x180.jpg 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">Djangoで簡単な「文字カウントメモ」を作ってみる</div><div class="blogcard-snippet internal-blogcard-snippet">この記事では、「Djangoを勉強したい！」「Pythonで何か作ってみたい」という人に向けて、Djangoを用いた簡単なWebアプリ作成の方法を実際に一緒に作りながら紹介していきます。プログラミング学習の助けになれば幸いです。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://ryuusan.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">ryuusan.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2020.05.16</div></div></div></div></a>



  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">はじめに &#8211; Ajaxとは？</a></li><li><a href="#toc2" tabindex="0">実装</a></li><li><a href="#toc3" tabindex="0">おわりに</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">はじめに &#8211; Ajaxとは？</span></h2>



<p class="wp-block-paragraph">Ajax(<strong>Asynchronous&nbsp;JavaScript&nbsp;and&nbsp;XML</strong>)は、それ自体が技術というわけではなく、一種のアプローチです。このAjaxを利用ことで、表示されているページをすべて更新することなく、一部のみを更新することができ、Webアプリケーションの高速化を行うことができます。</p>



<p class="wp-block-paragraph">よくGoogle MapsがAjaxを利用している例として挙げられます。Google Mapsはドラッグに合わせて、ページをリロードすることなく表示される範囲が滑らかに移動しますが、それはAjaxを利用しているためです。</p>



<p class="wp-block-paragraph">また、<strong>Asynchronous&nbsp;JavaScript&nbsp;and&nbsp;XML</strong>にはXMLの文字が入っていますが、JSONの方が軽く、JavaScriptで扱いやすいなどの理由から最近はXMLよりもJavaScriptの方がよく使われているそうです。今回もJSONを使って実装していきたいと思います。</p>



<h2 class="wp-block-heading"><span id="toc2">実装</span></h2>



<p class="wp-block-paragraph">テンプレートファイルは以下の通りです。今回はjQueryの$.ajaxメソッドを利用しているので、base.htmlでjQueryを読み込んでいます。</p>



<p class="wp-block-paragraph">getCookieから$.ajaxSetupまでは、csrftokenをいい感じにするために記述しています。送信フォームを使う場合は<strong>{% csrf_token %}</strong>をつけておけばDjangoが良い感じにしてくれるのですが、ajaxでPOSTする場合はこのように<strong>cookieから拾ってきたcsrftokenの内容を<span class="marker-under">X-CSRFToken</span>という名前でヘッダに設定する</strong>必要があります。</p>



<pre class="wp-block-code"><code>{% extends 'article/base.html' %}

{% block title %}
    My test page
{% endblock %}

{% block content %}
    &lt;ul>
        {% for article in article_list %}
            &lt;li>
                {{ article.article_text }}
                &lt;span class="add_good" id={{ article.id }}>&amp;hearts;&lt;/span>
                &lt;span id="good-count-{{article.id}}">{{ article.good_count }}&lt;/span>
            &lt;/li>
        {% endfor %}
    &lt;/ul>
    &lt;button onclick="location.href='{% url 'article:article_create' %}'">
        追加
    &lt;/button>
{% endblock %}

{% block extrajs %}
    &lt;script>
        function getCookie(name) {
            var cookieValue = null;
            if (document.cookie &amp;&amp; document.cookie !== '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i &lt; cookies.length; i++) {
                    var cookie = jQuery.trim(cookies&#91;i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) === (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }

        var csrftoken = getCookie('csrftoken');

        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }

        $.ajaxSetup({
            beforeSend: function (xhr, settings) {
                if (!csrfSafeMethod(settings.type) &amp;&amp; !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });

        $('.add_good').on('click', function(e) {
            article_id = $(this).attr("id");
            $.ajax({
                'url': '{% url "article:change_count" %}',
                'type': 'POST',
                'data': {
                    'id': article_id,
                },
                'dataType': 'json'
            }).done( response => {
                const response_id = response.id;
                const good_count = response.good_count;
                const element = '#good-count-' + response_id;
                $(element).text(good_count);
            });

        });
    &lt;/script>
{% endblock %}</code></pre>



<p class="wp-block-paragraph">モデルはこんな感じです。good_countがいいねの数に対応しています。ajaxでArticleのidをもらい、viewで対応するArticleのgood_countを増やしてからjsonで追加後のいいね数を返しています。</p>



<pre class="wp-block-code"><code>from django.db import models

# Create your models here.
class Article(models.Model):
    article_text = models.CharField(max_length=100)
    good_count = models.IntegerField(default=0)
    
    def __str__(self):
        return self.article_text</code></pre>



<p class="wp-block-paragraph">viewは以下の通りです。<strong>add_good_count_for_article</strong>が主にajaxの処理を行う関数です。<strong>return JsonResponse</strong>でJsonを返却しています。</p>



<pre class="wp-block-code"><code>from django.shortcuts import render
from .models import Article
from django.views.generic import ListView
from django.views.generic.edit import CreateView
from django.urls import reverse
from django.http import JsonResponse

# Create your views here.
class ArticleListView(ListView):
    template_name = 'article_list.html'
    model = Article
    

class ArticleCreateView(CreateView):
    model = Article
    fields = ('article_text', )
    
    def get_success_url(self):
        return reverse('article:article_list')
        

def add_good_count_for_article(request):
    article_id = request.POST.get('id')
    article = Article.objects.get(id=article_id)
    article.good_count += 1
    article.save()
    data = {
        'id': article_id,
        'good_count': article.good_count,
    }
    return JsonResponse(data)</code></pre>



<p class="wp-block-paragraph">urlは以下のように設定しています。</p>



<pre class="wp-block-code"><code>from django.urls import path
from . import views

app_name = 'article'
urlpatterns = &#91;
    path('', views.ArticleListView.as_view(), name='article_list'),
    path('create/', views.ArticleCreateView.as_view(), name='article_create'),
    path('change/', views.add_good_count_for_article, name='change_count')
]</code></pre>



<p class="wp-block-paragraph">トリミングと拡大をしているのでだいぶ荒いですが、このようにいいねを押すとリロードを挟まずにいいね数が増えていきます。変更はデータベースにも反映されているので、リロードを行ってもいいね数は変更された値のままです。(ListViewを使っているので、順序は変わるかもしれませんが)</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter size-large is-resized"><img fetchpriority="high" decoding="async" src="https://ryuusan.com/wp-content/uploads/2020/10/ajaxDjango.png" alt="" class="wp-image-360" width="388" height="196" srcset="https://ryuusan.com/wp-content/uploads/2020/10/ajaxDjango.png 322w, https://ryuusan.com/wp-content/uploads/2020/10/ajaxDjango-300x152.png 300w, https://ryuusan.com/wp-content/uploads/2020/10/ajaxDjango-320x163.png 320w" sizes="(max-width: 388px) 100vw, 388px" /></figure></div>



<h2 class="wp-block-heading"><span id="toc3">おわりに</span></h2>



<p class="wp-block-paragraph">今回はDjangoとajaxを利用していいね!を行うことができる簡単なWebアプリを実装しました。このアプリではいいねを何度も押すことができましたが、ユーザやIPアドレスなどで判別して一度しか押せないようにしたり、いいね！したらcssなどで色を変えたりすればより実用的になると思います。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ryuusan.com/django-ajax/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
