Djangoを触り始めるなら、まずは簡単なアプリケーションを作ってみましょう。今回の記事を参考に作ることで、データベースとの連携やデータベースからのデータの引き出し方、テンプレートの使い方や基本的なルーティングまでが理解できるようになると思います。
この記事を読み終わって理解できるようになれば、顧客受注管理システムや、To-doリストに登録したやることリストをTwitterで自分にリプライを返す。本棚アプリケーションや掲示板、簡易的なSNSシステムなどが作れるようになるでしょう。
カスタマイズや、後々のテンプレートとしても利用できるように最小構成でアプリケーションを作ることができますので、是非最後までご覧いただきあなただけのDjangoアプリケーションを作成してみてください。
まずはDjangoの環境構築を前回の記事を参考に行ってください。
Djangoprojectというディレクトリを作成し、移動してください。
Djangoprojectディレクトリに仮想環境を構築して、仮想環境をオンにしてから以下のコードを打ち込みます。
virtualenv) $ django-admin startproject orders virtualenv) $ cd orders virtualenv) $ python manage.py startapp myapp
ordersというディレクトリの中に、settings.pyというファイルがあるので以下を参考に書き換えてください。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp', ] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates'),], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] LANGUAGE_CODE = 'ja' TIME_ZONE = 'Asia/Tokyo' STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"), )
今回のアプリケーションを ’myapp’, として登録。
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates'),],
これでテンプレート(index.html)を使用する準備を行っています。
STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"), )
スタティックファイル、つまりCSSやJSフォルダをこれで扱えるようになります。
同じくordersディレクトリに urls.py というファイルがありますので、以下のように修正します。
from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^myapp/', include('myapp.urls')), url(r'^', include('myapp.urls',namespace='myapp')), url(r'^admin/', admin.site.urls), ]
このルーティングの書き方は現在は「こう書くんだな」くらいでOKです。
次に myapp ディレクトリ内に urls.py を新規作成します。
記載するコードは以下の通り。
from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index, name='index'), ]
index.html にアクセスしたら、テンプレートのindexを返す。
と思っていただいていいかと思います。
モデル、とはデータベースに何を保存するかを書き込んであるファイル。
と考えてください。
今回はTo-doアプリなので「やること」と「日時」を保存しましょう。
myapp ディレクトリの models.py を以下のように修正します。
from django.db import models class Posting(models.Model): message = models.CharField( max_length = 140, verbose_name = 'やること', ) created_at = models.DateTimeField( auto_now_add = True, verbose_name= '日時', )
Posting というクラスを作成し、message という項目で「やること」を保存する。
書き込んだ日時を created_at という項目で保存する。
と考えてください。
Djangoのモデル定義は公式サイトを見ていただくとわかるのですが、結構奥が深いです。
しかしながら、複雑なことをしないのであれば今回のサンプルで色々できるようになるはずです。
myapp ディレクトリに新規で forms.py というファイルを作成します。
from django import forms from myapp.models import Posting class PostingForm(forms.ModelForm): class Meta: model = Posting fields = ('message',) widgets = { 'message': forms.Textarea(attrs={'cols': 40, 'rows': 4}) }
Djangoにもとからある機能を使うことで、開発のスピードが上がりますね。
fields という項目があるのですが、他にも様々なフィールドを利用することができます。
widget という項目ではフォームに表示する内容を指定できます。To-doリストなのでテキストエリアを設定しています。
myapp ディレクトリにある views.py ファイルがアプリケーションの実際に動作するメイン部分となります。以下のようにコードを書きましょう。
import sys, codecs sys.stdout = codecs.getwriter('utf-8')(sys.stdout) from django.http.response import HttpResponse from django.shortcuts import (render, redirect,) from django import forms from myapp.models import Posting from .forms import PostingForm def index(request): form = PostingForm(request.POST or None) if request.method == 'POST': if form.is_valid(): form.save() return redirect('myapp:index') new_text = Posting.objects.all().order_by('-id') contexts = { 'form':form, 'new_text':new_text, } return render(request, 'index.html', contexts)
コードの理解として覚えておきたい箇所は
if request.method == 'POST': if form.is_valid(): form.save() return redirect('myapp:index')
この記述の仕方です。 POSTされたら保存、ということになっていて form.save() でデータベースに保存をしています。データベースに保存したあとはindex.htmlをリダイレクトする指示を書いています。
new_text = Posting.objects.all().order_by('-id')
これはデータベースに登録されたデータを呼び出すためのものです。 .order_by(‘-id’) とすることで、保存されたデータが新しいものから順に並びます。 データベースの項目で並び替えを行ったりもできますのでDjangoのメソッドを調べてみると良いでしょう。
contexts = { 'form':form, 'new_text':new_text, } return render(request, 'index.html', contexts)
ここではテンプレート(index.html)で使いたいものを辞書で渡していると考えてください。
contexts で辞書としたものを render関数の第三引数に設定します。
辞書の中はもっと増えても構いませんが、今回はDjangoに用意されているフォーム、データベースに登録されたテキストデータを辞書として受け渡しします。
myapp ディレクトリに admin.py というファイルがあるので、以下のようにコードを書きます。
from django.contrib import admin from myapp.models import Posting class PostingAdmin(admin.ModelAdmin): list_display = ('id','message','created_at') admin.site.register(Posting,PostingAdmin)
こうしておくことでDjangoに最初から準備されている管理サイトで、データベースに書き込まれた内容を確認することができます。
virtualenv) $ python manage.py createsuperuser
このコマンドを実行し、Django管理サイトの管理者登録をしておきましょう。
bootstrapを利用しているので、同じ状況にするには myapp ディレクトリに static というフォルダを作成し、そこにCSSなどを放り込んでいきましょう。
myapp ディレクトリの中に templates というフォルダを作りその中にbase.html を以下のように保存しましょう。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="../static/css/bootstrap.min.css" rel="stylesheet"> <link href="../static/css/custom.css" rel="stylesheet"> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="../static/js/bootstrap.min.js"></script> <title></title> </head> <body> {% block body %} {% endblock %} </body> </html>
テンプレートなので、何度も使う箇所「ヘッダー」「フッター」などをbase.htmlとして作ることができます。
{% block body %} {% endblock %}
WordPressなどと同じようなイメージでOKです。
引き続きindex.htmlを作成しましょう。
{% extends "base.html" %} {% block body %} <div class="container"> <div class="row"> <div class="col-md-12"> <form action="{% url 'myapp:index' %}" method="post"> <div class="row"> {% for field in form %} <label class="col-sm-3">{{ field.label_tag }}</label> <label class="col-sm-7">{{ field }}</label> {% endfor %} <input type="submit" class="btn btn-primary" value="登録"> {% csrf_token %} </div> </div> </form> {% include "to_do.html" %} </div> </div> </div> {% endblock %}
なんとなくわかりましたか?Djangoのテンプレートによって、base.htmlに上記URLがインクルードされるイメージです。
<form action="{% url 'myapp:index' %}" method="post">
フォームを送信したら views.py のindex を実行する、という意味合いです。
フォームタグの終了前に
{% csrf_token %}
を書いておくことでクロスサイトリクエスト・フォージェリ対策になるわけです。
この記載を忘れるとフォームが送信できません。
{% for field in form %} <label class="col-sm-3">{{ field.label_tag }}</label> <label class="col-sm-7">{{ field }}</label> {% endfor %}
これでDjangoの用意してくれているフォームを呼び出しています。
エラーバリデートなどの処理も準備されているので利用する場合は、Djangoのサイトを参考にしてください。
to-do.html というファイルを以下のように作ります。
<div class="row"> {% for i in new_text %} <div class="col-md-4"> <p>{{ i.message }} - {{ i.created_at }}</p> </div> {% endfor %} </div>
単純に登録されたテキストと、自動保存された日時データを取得し表示します。
データベース・アプリケーション・テンプレートが完成したのでデータベースの最後の処理を行います。
virtualenv) $ python manage.py makemigrations myapp virtualenv) $ python manage.py migrate
マイグレーションが成功すれば、以下のコマンドでサーバーを起動させましょう。
virtualenv) $ python manage.py runserver
これでDjangoで作るTo-doアプリケーションの完成です。