Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

AngularJS1 + Django REST Frameworkに再挑戦 その2 Angular Templates in Django Part 1

概要

AngularJS1 + Django REST Frameworkに再挑戦 その2 Angular Templates in Django Part 1

参考動画

Django + AngularJS | Coding For Entrepreneurs

Angular Templates in Django Part 1

  • src/ang/init.py と、src/ang/views.pyを作成する。

  • views.pyは以下のように設定する。

from django.shortcuts import render


def get_angular_template(request, path=None):

    return render(request, "ang/app/blog-list.html", {})
  • templates/ang/app/blog-list.htmlファイルを作成する。内容は、try-angular1.5のblog-list.htmlをひとまずコピペする。

  • また、templates/ang/home.htmlには、try-angular1.5のindex.htmlをコピペする。

  • さらに、ang-srcの、img, js, jsonなどのstaticフォルダを, src/static/に丸ごとコピーして配置する。

  • python manage.py collectstaticで、try-angularからコピーしてきたファイルをまとめる。

  • この状態で、python manage.py runserverしてみる。。。errorは出ないけどまだ空白のページのまま。検証してみると、Uncaught SyntaxError: Unexpected token <という表示が出ている。多分ここのerrorは、djangoでrenderingするときのstaticfileの扱い方の問題だと思われるので、次章で解決する。

Static Files in Django & Angular

  • {% load staticfiles %}を追記する。

  • 読み込みたいstaticfileを'{% static "" %}'で囲む。まとめると以下のようになる。

{% load staticfiles %}
...
    <script src='{% static "js/external/dirPagination.js" %}' ></script>
    <script src='{% static "js/app/app.module.js" %}' ></script>
    <script src='{% static "js/app/app.config.js" %}' ></script>


    <script src='{% static "js/app/core/post/post.module.js" %}' ></script>
    <script src='{% static "js/app/core/post/post.service.js" %}' ></script>

    <script src='{% static "js/app/blog-detail/blog-detail.module.js" %}' ></script>
    <script src='{% static "js/app/blog-detail/blog-detail.component.js" %}' ></script>
    <script src='{% static "js/app/blog-list/blog-list.module.js" %}' ></script>
    <script src='{% static "js/app/blog-list/blog-list.component.js" %}' ></script>


    <script src='{% static "js/app/utils/confirm-click/confirm-click.module.js" %}' ></script>
    <script src='{% static "js/app/utils/confirm-click/confirm-click.directive.js" %}' ></script>

    <script src='{% static "js/app/utils/try-nav/try-nav.module.js" %}' ></script>
    <script src='{% static "js/app/utils/try-nav/try-nav.directive.js" %}' ></script>
...
  • これでhome.htmlのerrorは無くなった!でも相変わらず空白のページ。shellは以下のように延々と表示されている。
[21/Jan/2017 23:47:19] "GET /json/posts.json HTTP/1.1" 200 2316
[21/Jan/2017 23:47:20] "GET /json/posts.json HTTP/1.1" 200 2316
[21/Jan/2017 23:47:20] "GET /json/posts.json HTTP/1.1" 200 2316
...
  • どうもjsonファイルの読み込みに問題があるらしい。/json/posts.jsonが読み込めていないので、その部分の読み込みのルートを修正する。該当箇所は、static/js/app/post/post.service.js にある。以下のようにurlを修正する。
...
            var url = '/static/json/posts.json'
...
  • でも、まだ空白ページは続く。。。

Angular Templates in Django Part 2

  • src/blog/blog/urls.pyを設定する。
...
# 普通にviewをimportするだけ
from ang.views import get_angular_template
...
# 正規表現でget_angular_templateのurlを設定する
    url(r'^api/templates/(?<item>[A-Za-z0-9\_\-\.\./]+)\.html$', get_angular_template),
...
  • さらに、ang/views.pyに、以下の通り、itemを表示させるような設定にしてみる。
def get_angular_template(request, item=None):
    print(item)
    return render(request, "ang/app/blog-list.html", {})
  • 上記を設定して、http://127.0.0.1:8000/api/templates/blog-list.templates.htmlに、アクセスする。そうすると、blog-list.templates とshellに表示される。つまり、127.0.0.1:8000/api/templates/blog-list.templates.htmlの、blog-list.templatesの部分がitemとして表示されている。これはurlからviewが取得している。この性質を利用して、urlを設定していく。

  • ang/views.pyに設定する。

import os

from django.conf import settings
from django.http import HttpResponse, Http404

from django.views.generic import View

from django.shortcuts import render

class AngularTemplateView(View):
    def get(self, request, item=None, *args, **kwargs):
        template_dir_path = settings.TEMPLATES[0]["DIRS"][0] #settingsのTEMPLATESのDIRの1番目の要素。
        final_path = os.path.join(template_dir_path, "ang", "app", item + ".html") #templates/ang/app/templateのhtml指定
        try:#templateがある場合は、返す。
            html = open(path)
            return HttpResponse(html)
        except:#ない場合は404
            raise Http404
  • urls.pyを修正する。
rl(r'^api/templates/(?P<item>[A-Za-z0-9\_\-\.\./]+)\.html$', AngularTemplateView.as_view()),
  • この状態で、127.0.0.1:8000/api/templates/blog-list.htmlにアクセスしてみる。。。404が表示されてしまう。Not Found: /api/templates/blog-list.htmlと表示されてしまうので、templateの場所がうまく指定されてないのかもしれない。

  • ang/views.pyのhtml = open(path)html=open(final_path)に修正する。。。表示された!pathが間違ってた〜〜!

  • このままでは、angularからのcontextなどが引き継がれていないので、angularJS側のurlのroutingを修正する。blog-list/component.jsなどなど。

// blog-list.component.js
...
templateUrl: '/api/templates/blog-list.html'
...
  • さらに、app.config.jsも修正する。
              when("/about", {
                templateUrl: "/api/templates/about.html"
              }).
  • 表示された〜〜!

  • まとめると以下のようになるはず。

    • staticファイルをdjangoのプロジェクトに持ってくる。js,img,cssなど。
    • それぞれのテンプレートファイルに、{% static %}を設定する。
    • さらに、javascriptのstaticファイルに関しては、絶対パスでurlを指定する。例えば、var url = '/static/json/posts.json'など。
    • angularのtemplatesのhtmlファイルにアクセスするためのurlは、url(r'^api/templates/(?P<item>[A-Za-z0-9\_\-\.\./]+)\.html$', AngularTemplateView.as_view()),などで設定しておく。
    • angularの各種moduleが、上記のtemplates urlにアクセスできるように、angular関連のjsファイルのtemplateURLのファイルパスを設定変更する。