LoginSignup
138
144

More than 3 years have passed since last update.

Django REST frameworkでTodoアプリを作ってみる

Last updated at Posted at 2015-06-04

Django REST frameworkを使用して、シンプルなTODOアプリを作成します。

作成するアプリの特徴

  • TODOの作成/完了を管理するシングルページアプリ
  • SQLite3にTODOを保管
  • Django REST frameworkを使用
  • RESTfulなAPIを作成

環境・バージョン
Windows 7
Python 3.4.3
Django 1.8.2
Django REST framework 3.1.2

成果物
https://github.com/koji-ohki-1974/django-rest-todo

準備

PythonおよびDjangoは導入済みとします。

Django REST frameworkの導入

以下のコマンドを実行し、Django REST frameworkを導入します。

pip install djangorestframework

プロジェクトの作成

Djangoのプロジェクトを作成します。任意のフォルダで、以下のコマンドを実行します。

django-admin.py startproject django_rest_todo

データベースのセットアップ

データベースを初期化し、スーパーユーザーを作成します。

cd django_rest_todo
python manage.py migrate
python manage.py createsuperuser

スーパーユーザーのIDとメールアドレス、パスワードを設定します。

項目
Username admin
Email address admin@any.com
Password admin

サーバーの起動・動作確認

以下のコマンドを実行します。

python manage.py runserver

ブラウザを起動しhttp://localhost:8000/にアクセスします。
プロジェクトの作成が成功していれば、「It worked!」という画面が表示されます。

「CTRL + C」でサーバーを終了します。

アプリケーションの作成

プロジェクトフォルダで、以下のコマンドを実行し、アプリケーションを作成します。

cd django_rest_todo
django-admin.py startapp api

プロジェクトの設定を変更しておきます。「settings.py」を以下の通り変更します。

settings.py(抜粋)
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'django_rest_todo.api',
)

MIDDLEWARE_CLASSES = (
#  'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
#  'django.middleware.csrf.CsrfViewMiddleware',
#  'django.contrib.auth.middleware.AuthenticationMiddleware',
#  'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
#  'django.contrib.messages.middleware.MessageMiddleware',
#  'django.middleware.clickjacking.XFrameOptionsMiddleware',
#  'django.middleware.security.SecurityMiddleware',
)

APIの作成

Todoモデル

Todoのモデルを定義します。「api/models.py」を編集し、Todoクラスを追加します。

api/models.py
from django.db import models

class Todo(models.Model):
    text = models.TextField()

モデルの定義が完了したら、データベースに反映します。以下のコマンドを実行します。

cd ..
python manage.py makemigrations api
python manage.py sqlmigrate api 0001
python manage.py migrate

シリアライザの作成

モデルをJSONにマッピングするシリアライザを定義します。
「api/serializers.py」を作成します。

api/serializers.py
from .models import Todo
from rest_framework import serializers

class TodoSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Todo
        fields = ('id', 'text')

ビューの作成

REST用のビューを作成します。「api/views.py」にTodoViewSetクラスを追加します。

api/views.py
from rest_framework.viewsets import ModelViewSet
from .models import Todo
from .serializers import TodoSerializer

class TodoViewSet(ModelViewSet):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

API ルーティング

APIを処理できるようにルーティングの設定をおこないます。
「urls.py」を変更します。

urls.py
from django.conf.urls import include, url
from rest_framework.routers import DefaultRouter
from .api import views

router = DefaultRouter()
router.register(r'todos', views.TodoViewSet)

urlpatterns = [
    url(r'^api/', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

サーバーの起動・動作確認

再度、サーバーを起動し、APIの動作確認をおこないます。以下のコマンドを実行します。

python manage.py runserver

ブラウザを起動し、以下にアクセスします。

http://localhost:8000/api/
http://localhost:8000/api/todos/

「CTRL + C」でサーバーを終了します。

フロントエンドの作成

静的ファイル

静的ファイル(.htmlと.js)の配置場所を指定します。「settings.py」を編集し、以下を追加します。

settings.py
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)

「static」フォルダを作成します。

mkdir static

HTMLファイル

Todoリストの画面を作成します。「static/index.html」を作成します。

static/index.html
<!doctype html>
<html ng-app="djangoTodo">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Django REST framework Todo App</title>

    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
    <style>
        html                    { overflow-y:scroll; }
        body                    { padding-top:50px; }
        #todo-list              { margin-bottom:30px; }
    </style>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
    <script src="core.js"></script>

</head>
<body ng-controller="mainController">
    <div class="container">

        <div class="jumbotron text-center">
            <h1>Todoリスト <span class="label label-info">{{ todos.length }}</span></h1>
        </div>

        <div id="todo-list" class="row">
            <div class="col-sm-4 col-sm-offset-4">

                <div class="checkbox" ng-repeat="todo in todos">
                    <label>
                        <input type="checkbox" ng-click="deleteTodo(todo.id)"> {{ todo.text }}
                    </label>
                </div>

            </div>
        </div>

        <div id="todo-form" class="row">
            <div class="col-sm-8 col-sm-offset-2 text-center">
                <form>
                    <div class="form-group">

                        <input type="text" class="form-control input-lg text-center" placeholder="Todoを入力してください" ng-model="formData.text">
                    </div>

                    <button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">追加</button>
                </form>
            </div>
        </div>

    </div>

</body>
</html>

JavaScriptファイル

JavaScriptで、APIをコールする処理を記述します。「static/core.js」を作成します。

static/core.js
var djangoTodo = angular.module('djangoTodo', []);

function mainController($scope, $http) {

    $scope.readTodos = function() {
        $http.get('/api/todos/')
            .success(function(data) {
                $scope.formData = {};
                $scope.todos = data;
                console.log(data);
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };

    $scope.createTodo = function() {
        $http.post('/api/todos/', $scope.formData)
            .success(function(data) {
                console.log(data);
                $scope.readTodos();
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };

    $scope.deleteTodo = function(id) {
        $http.delete('/api/todos/' + id + '/')
            .success(function(data) {
                console.log(data);
                $scope.readTodos();
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };

    $scope.readTodos();

}

リダイレクト

トップページ「/」へのリクエストを「static/index.html」にリダイレクトするように設定します。「urls.py」を変更します。

urls.py
from django.conf.urls import include, url
from django.views.generic import RedirectView
from rest_framework.routers import DefaultRouter
from .api import views

router = DefaultRouter()
router.register(r'todos', views.TodoViewSet)

urlpatterns = [
    url(r'^api/', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    url('', RedirectView.as_view(url='/static/index.html')),
]

動作確認

サーバーの起動・動作確認

サーバーを起動します。

python manage.py runserver

ブラウザを起動しhttp://localhost:8000/にアクセスします。
Todoリストが表示されれば完成です。

138
144
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
138
144