Djangoroidの奮闘記

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

AngularJS1 + Django REST Frameworkに再挑戦 その3 Post Objects API Integration

概要

AngularJS1 + Django REST Frameworkに再挑戦 その3 Post Objects API Integration

参考動画

Django + AngularJS | Coding For Entrepreneurs

Post Objects API Integration

  • http://127.0.0.1:8000/api/posts/にアクセスすると、djangoのデータベースに保存されている、postのjsonデータが表示される。今の127.0.0.1:8000に表示されるデータは、static/json/posts/posts.jsonデータが元になっている。そのため、これをデータベースと連動させたい。

  • まず、js/core/post/post.service.jsを修正する。postのデータの元をdjango rest frameworkのpostsのurlに単純に変更してみる。

// var url = '/static/json/posts.json'
var url = '/api/posts/'
  • http://127.0.0.1:8000/にアクセスすると、リストが表示されない。。。Error: $resource:badcfg Response does not match configured parameterが表示されている。

  • 以下のようにpost.service.jsを修正してみる。

angular.
    module('post').
        factory('Post', function($resource){
            var url = '/api/posts/'
            return $resource(url, {}, {
                query: {
                    method: "GET",
                    params: {},
                    isArray: true,
                    cache: false,
                    transformResponse: function(data, headerGetter, status){
                        console.log(data)
                        return data
                    }
                    // interceptor
                },
  • それでも表示されない。。console.logにはなぜか、htmlが表示されている。なぜだ。。。

  • 理由は、var url = '/api/posts/'を設定しており、/api/postsのページのhtmlデータを持ってきてたからだった。。。ということで、ここには、別のURLを設定する必要がある。

  • app.config.jsを修正する。

angular.module('try').
    config(
        function(
          $locationProvider,
          $resourceProvider,
          $routeProvider
          ){
          $locationProvider.html5Mode({
              enabled:true
            })

          $resourceProvider.defaults.stripTrailingSlashes = false;
  • resourceProviderについては、以下の公式サイトを参照。$resourceの働きを変更するものらしい。

https://docs.angularjs.org/api/ngResource/provider/$resourceProvider

  • $resourceProvider.defaults.stripTrailingSlashes = false;は、Restfulなdataを持ってくるために必要なことらしい。
By default, trailing slashes will be stripped from the calculated URLs, which can pose problems with server backends that do not expect that behavior. This can be disabled by configuring the $resourceProvider
  • これでもまだerrorは出てしまう。。。ただ、logにjsonデータは表示されているので、あと一歩!

  • post.service.jsを修正する。dataをAngular.Jsonで、angular用のデータに修正する。

                    transformResponse: function(data, headerGetter, status){
                        console.log(data)
                        var finalData = angular.fromJson(data)
                        return finalData.results
                    }
  • おおーーこれで、表示されるようにはなった。ただ、titleのURLのリンクが、/blogになっており、うまくdetailページが表示されない。

  • 理由は、djangoREST Frameworkは、detailpageの表示URLがslugになっていたことみたいやな。

'use strict';

angular.
    module('post').
        factory('Post', function($resource){
            // : slug/を付け加える。
            var url = '/api/posts/:slug/'
            return $resource(url, {}, {
                query: {
                    method: "GET",
                    params: {},
                    isArray: true,
                    cache: false,
                    transformResponse: function(data, headerGetter, status){
                        console.log(data)
                        var finalData = angular.fromJson(data)
                        return finalData.results
                    }
                    // interceptor
                },
                get: {
                    method: "GET",
                    // paramsをslugに修正する。
                    params: {"slug": "@slug"},
                    // isArrayをfalseにする。
                    isArray: false,
                    cache: false,
                }
            })
  • app.config.jsのblog-detailの箇所のURLを、修正する。slugをつける。
              when("/blog/:slug", {
                  template: "<blog-detail></blog-detail>"
              }).
  • blog-detail.component.js を修正する。
angular.module('blogDetail').
    component('blogDetail', {
        templateUrl: '/api/templates/blog-detail.html',
        controller: function(Post, $http, $location, $routeParams, $scope){
            Post.get({"slug": $routeParams.slug}, function(data){
                $scope.post = data
            })
  • blog-list.htmlを修正する。id->slugに修正する。
        <a ng-href='/blog/{{ post.slug }}' ng-if='post.image'>
          <img ng-src='{{ post.image }}' class='img-responsive'>
        </a>
        <div class="caption">
          <h3><a ng-href='/blog/{{ post.slug }}'>{{ post.title }}</a></h3>
          <p>{{ post.text }} {{ post.publishDate }}</p>
          <p><a ng-href='/blog/{{ post.slug }}' class='btn btn-primary'>View</a></p>
  • それでも出てこない。。。なんでだ。。。と思ったら、api/postsのデータにslugを表示させてなかったのが、原因だった〜。

  • なので、次章ではこれを修正するらしい〜〜!