-
Notifications
You must be signed in to change notification settings - Fork 0
Home
資料: Djangoフレームワークの紹介
この資料の中にデモとして載っている ToDo アプリ(タスク管理、やることリスト)をハンズオン形式で実装します。
元のPython環境を汚さないため、今回は Python の仮装環境を使います。
$ python3 -m venv venv
$ . venv/bin/activateUbuntu の場合、以下を入れておかないとダメかもしれない。
$ apt-get install python3-venv> python -m venv venv
> venv/Scripts/activate$ conda create --name venv python
$ source activate venv> activate venv- Django==2.0
- docutils==0.14
(venv) $ pip install django
(venv) $ pip install django-debug-toolbar
(venv) $ pip install docutils(venv) $ conda install django
(venv) $ conda install -c conda-forge django-debug-toolbar
(venv) $ conda install docutils
(venv) $ django-admin startproject myprojectmyproject
|-- manage.py 管理スクリプト
|-- myproject
|-- __init__.py 初期化処理スクリプト
|-- settings.py 設定情報
|-- urls.py URL管理
|-- wsgi.py Webアプリのメイン
$ cd myproject
$ python manage.py runservermyproject/settings.py をエディタでひらく。
デフォルトでは sqlite3 を使うように設定されている。このまま sqlite3 を使う。
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}デフォルトでは、管理画面のUIやエラーメッセージ、日時の扱いが英語/標準時に設定されている。
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
これを日本語/日本時間に設定するには以下のように設定を変更する。
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'todo という名前のアプリケーションを作成します。
(venv) $ python manage.py startapp todoディレクトリ (フォルダ)の構成は以下のようになります。
.
|-- manage.py
|-- myproject
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- mqq wsgi.py
|-- todo
|-- __init__.py
|-- admin.py
|-- apps.py
|-- migrations
| |-- __init__.py
|-- models.py
|-- tests.py
|-- views.py
todoの下に templatesディレクトリを作成しておきます。
|-- templates/ 追加
(venv) $ mkdir todo/templates(venv) > md todo\templates
今回作成するアプリケーションの名前 todo を以下のように settings.py の INSTALLED_APPS リストに追加します。
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo', # 追加
]WebアプリではMVCアーキテクチャを採用しているものが多いです。
M モデル データ構造
V ビュー ページ
C コントロール モデルとビューをつなぐ制御
Django は MVC に似ていますが、MTV アーキテクチャというものを採用しています。 大部分は MVC アーキテクチャに似ていますが同じ「ビュー」という用語が別の意味で使われているので注意です。
M モデル データ構造
T テンプレート ページのデザイン
V ビュー ページの表示処理(その中でモデルとの入出力も扱う)
TODOのデータを扱うモデルクラスを models.py にクラスとして定義します。 このクラスのインスタンス1つが、データベース上の1レコードに相当します。
データベースに登録する1レコードの内容は以下の3つの項目とします。
* 名称 タスク/やることを表す文字列
* 完了 タスク/やることが完了したことを示すフラグ
* 作成日時 タスク/やることを作成した日時
これを Django のモデルとして表すと以下のようになります。
from django.db import models
# Create your models here.
class Todo(models.Model):
name = models.CharField("名称", max_length=50)
done = models.BooleanField("完了")
created_at = models.DateTimeField("作成日時", auto_now_add=True)
def __str__(self):
return self.nameモデルの定義内容をデータベースの管理情報として登録します。
(venv) $ python manage.py makemigrations todo
(venv) $ python manage.py migratetodo/admin.py
Todoモデルを管理画面に登録
from django.contrib import admin
from .models import Todo
# Register your models here.
admin.site.register(Todo)Todoモデルを編集するためのフォームクラスを作成します。 todo/forms.py を作成して、以下の内容を記述します。
from django import forms
from .models import Todo
class TodoForm(forms.ModelForm):
class Meta:
model = Todo
fields = ['name', 'done']ModelFormクラスを継承しているため、Todoモデルのフィールドから自動的にフォームフィールドが生成されます。
from django.shortcuts import render, redirect, get_object_or_404
from .models import Todo
from .forms import TodoFormdef index(request):
# GETパラメータに ?all=1 と指定された場合は全件を表示
if request.GET.get('all') == '1':
queryset = Todo.objects.all()
else:
# 特に指定がない場合は未完了のレコードのみ
queryset = Todo.objects.filter(done=False)
# 作成日時で降順にソート
todo_list = queryset.order_by('-created_at')
return render(request, 'index.html', {'todo_list': todo_list})def add(request):
# GETメソッドの場合は、データを渡していないフォーム
# POSTメソッドの場合は、POSTされたデータを渡したフォームを生成
form = TodoForm(request.POST or None)
if form.is_valid(): # 入力内容の検証を実行(データが渡されていないフォームの場合は常にFalse)
form.save() # データベースに保存 (ModelForm.save()メソッド)
return redirect('index') # 一覧表示にリダイレクト
return render(request, 'add.html', {'form': form})def edit(request, pk):
# データベースから既存のレコードを取得
# 指定されたpkと一致するレコードがない場合には404 NotFoundのレスポンスを返す
todo = get_object_or_404(Todo, pk=pk)
# 既存のデータ(Todoクラスのインスタンスを指定したフォーム)
form = TodoForm(request.POST or None, instance=todo)
if form.is_valid():
form.save() # データベースに保存
return redirect('index') # 一覧にリダイレクト
return render(request, 'edit.html', {'form': form})def done(request, pk):
# データベースから既存のレコードを取得
todo = get_object_or_404(Todo, pk=pk)
todo.done = True # 完了扱いとする
todo.save() # データベースに保存
return redirect('index')from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('todo.urls')), # todoアプリケーションのurls.pyを含める
]from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'), # 一覧表示
path('add', views.add, name='add'), # 追加
path('<int:pk>/edit', views.edit, name='edit'), # 編集
path('<int:pk>/done', views.done, name='done'), # 完了
]todo/templates/index.html
<html><body>
<h1>TODO</h1>
<div>
<a href="{% url 'index' %}">未完了</a>
<a href="{% url 'index' %}?all=1">全部</a>
<a href="{% url 'add' %}">追加</a>
</div>
<ul>
{% for todo in todo_list %}
<li>
{% if todo.done %}
<strike>{{ todo.name }}</strike>
{% else %}
{{ todo.name }}
{% endif %}
<a href="{% url 'edit' pk=todo.pk %}">編集</a>
<a href="{% url 'done' pk=todo.pk %}">done</a>
</li>
{% endfor %}
</ul>
</body></html>todo/templates/add.html
<html><body>
<h1>追加</h1>
<div>
<a href="{% url 'index' %}">未完了</a>
<a href="{% url 'index' %}?all=1">全部</a>
<a href="{% url 'add' %}">追加</a>
</div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">保存する</button>
</form>
</body></html>todo/templates/edit.html
<html><body>
<h1>編集</h1>
<dev>
<a href="{% url 'index' %}">未完了</a>
<a href="{% url 'index' %}?all=1">全部</a>
<a href="{% url 'add' %}">追加</a>
</dev>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">保存する</button>
</form>
</body></html>(venv)$ pyhon manage.py runserver(venv) $ deactivate(venv) $ source deactivate(venv) > deactivate