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のファイルパスを設定変更する。