Django+Wagtail+CodeRedCMSでAjaxしてみた件  備忘録

# Wagtail/CodeRedCMS
CodeRedCMSはDjango/Wagtailの仕組みの上に作られたCMS環境です。
デザイン上の新奇性を大きく求めなければ、インストールしたままであまりカスタマイズすることなくサイトの構築ができそうな感じです。

# Ajax
ページの遷移を伴わずに、コンテンツの内容を変化させる仕組みでそう珍しくもない気がします。
JQueryを使って実装するのが普通なのでしょうが、Django/Wagtail/CoderedCMSとメタなルールの中に組み込むのが面倒に思えてしまいました。
今回は、ある程度コンテンツの中で完結してしまう様な方法として素のJavaScriptをCMS監理下のページに書き込むことで実現してみました。
~~そんなにカスタマイズしたくないのか~~



## サマリー
0.CodeRedCMSのインストールなど
1.RESPONSIVE GRID ROW の COLUMN
2.XMLHttpRequestによって非同期呼出し
3.DOMの内容を差し変える
4.サービスの作成
5.動作サンプル


## 0.CodeRedCMSのインストールなど
インストール等については以前投稿したこちらを参照していただければと思います。
　→ [nginx+Django+CodeRedCMSを立てた件 備忘録](https://qiita.com/sekirei/items/6f7dfdaabecec984883a)



## 1.RESPONSIVE GRID ROW の COLUMN
CodeRedCMSの 「RESPONSIVE GRID ROW」 の COLUMN部品ではHTMLを直接記入することが出来るので、ここにHTMLの部品とJavaScriptでの非同期リクエストとDOMの差し替えのコードを書いてしまう。

![スクリーンショット 2019-10-13 21.40.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358557/84ace985-ef83-e8ad-39d5-d273be751a5c.png)

　　↓↓↓


![スクリーンショット 2019-10-13 21.37.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358557/56096001-d7d4-0f1c-265e-b202896ba4f1.png)

内容全文は以下。GETリクエストであればこのくらい。

```
<br>
<button id="aiXhrButton"  onclick="requestAiXhr( true );">XHR ボタン</button>

<script>
    function createHttpRequest(){
        request = new XMLHttpRequest();
        return request;
    }
    function on_responseAiXhr(obj)
    {
        text  = obj.responseText;
        var target = document.getElementById('insertpoint');
        target.innerHTML = text;
    }

    function requestAiXhr( async ){
        var vurl = "/aixhr/";
        var httpoj = createHttpRequest();
        httpoj.open( 'GET' , vurl , async );

        httpoj.onreadystatechange = function() {
            if (httpoj.readyState==4) {
                on_responseAiXhr(httpoj);
            }
        }
        httpoj.send();
    }
</script>
<div id="insertpoint"><p>XHR 差込みポイント</p></div>
```

## 2.XMLHttpRequestによって非同期呼出し

個々にメモをすると。。。

```
        var vurl = "/aixhr/";
        var httpoj = createHttpRequest();
        httpoj.open( 'GET' , vurl , async );
```
createHttpRequestの中で new XMLHttpRequest()したリクエストのオブジェクトにメソッドとURLを指定。
URLの書き方は後々ハマリどころに。。。
[ → 4.サービスの作成](https://qiita.com/drafts/3d10b36ff843cb6acb65#4%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E4%BD%9C%E6%88%90)
今回同一のサービス内に呼び出し先を用意したので、ベースURL以下のパスを記述しました。

```
        httpoj.onreadystatechange = function() {
            if (httpoj.readyState==4) {
                on_responseAiXhr(httpoj);
            }
        }
```
レスポンスを on_responseAiXhrで受け取るようにしておく。

```
        httpoj.send();
```
そしてリクエストを実行。


## 3.DOMの内容を差し変える


今回は scriptタグの外側に以下のように記述して差し込み場所を用意。
```<div id="insertpoint"><p>XHR 差込みポイント</p></div>```

XHRのレスポンスを受けた処理の中で、insertpointというIDで検出してDOM要素の内容を書き換えます。

```
    function on_responseAiXhr(obj)
    {
        text  = obj.responseText;
        var target = document.getElementById('insertpoint');
        target.innerHTML = text;
    }
```


## 4.サービスの作成
じつはRequestの呼び出し先の方をどうやって用意しようかと考えていたのですが、別のサーバーにするのもどうかと思い CoderedCMSのproject内に生のDjangoでアプリを作ってみました。
はじめての Django アプリ作成...を参考に。
https://docs.djangoproject.com/ja/2.2/intro/tutorial01/#write-your-first-view

今度は CodeRedCMSをインストールしたサーバ側での操作になります。

```
$ python manage.py startapp aixhr
```
プロジェクトフォルダ内で上記を実施して今回はaixhrという名前のアプリケーションを作成。
ここではcrcsiteというプロジェクト内での話とします。

views.pyを作って何かしらレスポンスを返しておく。

```python:crcsite/aixhr/views.py

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world. Trial to XHR.")
```

このアプリ内でのURLの処理を views.indexでやるということをurls.pyに書きます。

```python:crcsite/aixhr/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
```

そして親になるCodeRedCMSプロジェクトの方にこのパスを参照するように記述の追加。

```python:crcsite/crcsite/urls.py
urlpatterns = [
    # Admin
    path('django-admin/', admin.site.urls),
    path('admin/', include(coderedadmin_urls)),

    # XHR trial
    path('aixhr/', include('aixhr.urls')),　　#追加

```

アプリケーションを有効に。

```python:crcsite/settings/base.py
INSTALLED_APPS = [
    # This project
    'website',
    'aixhr',　　#追加

　　・・・・

```

あとはmigration してから サービスを再起動

## ５.動作サンプル
動作サンプルは以下。ハードコーディングされた（？笑）天気予報が現れます。
[→１０月のスケジュールと天気](http://118.27.36.214:8080/schedule/)

（ただし内容は予告なく変更します。ダウンしていることもあるかと思います。

---
参考荷させて頂いた記事
jQueryを使わずにDjangoでAjax！
https://qiita.com/menta/items/79422df67e5f3c9b2325