プロジェクトの作成
django-admin startproject {プロジェクト名}
アプリケーションの作成
manage.pyのあるディレクトリで以下のコマンド
python manage.py startapp {アプリ名}
url用のディレクトリを作成
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
{プロジェクト名}/urls.py
こちらのurlpatterns
には各アプリケーションからのURLConfを書く
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
各種設定
タイムゾーンと言語コード
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
データベースの作成
migrate
コマンド...ファイルのデータベース設定に従って必要なすべてのデータベースのテーブルを作成する
python manage.py migrate
モデルを反映させる
python manage.py makemigrations {アプリケーション名}
makemigrations
を実行することで、Djangoのモデルに変更があったことを伝えそして変更を反映する形で保存することができる。
Django Adminについて
Django Adminは管理者だけが入ることができるWebサイトの情報をブラウザから編集できるページです。
管理者だけが入れるadminサイトには管理ユーザを作成することでアクセスすることができます。
python python manage.py createsuperuser
管理サーバの起動
管理サーバの起動にはpython manage.py runserver
でサーバを起動します。
そのあとローカルドメインの"/admin/"つまりはhttp://127.0.0.1:8000/admin/にアクセスします。
アクセスすると下記のような画面が表示され管理ユーザで作成したUsername
とPassword
を入力します。
アプリをadmin上で編集できるようにする
アプリをadmin上で編集できるようにするには{アプリ名}/admin.py
を編集します。
例えばQuestionオブジェクトがadminインターフェースを持つということをadminに伝える場合は以下のように書きます。
from django.contrib import admin
from .models import Question
admin.site.register(Question)
オーバービュー
ビューとは
Djangoのアプリケーションにおいて特定の機能を提供するウェブページの「型(type)」です。
ブログアプリケーションだと以下のようなビューがあるはずです。
- Blog ホームページ - 最新エントリーをいくつか表示
- エントリー詳細ページ - 1エントリーへのパーマリンク (permalink) ページ
- 年ごとのアーカイブページ - 指定された年のエントリーの月を全て表示
- 月ごとのアーカイブページ - 指定された月のエントリーの日をすべて表示
- 日ごとのアーカイブページ - 指定された日の全てのエントリーを表示
- コメント投稿 - エントリーに対するコメントの投稿を受付
Djangoにおけるビュー
Djangoではウェブページとコンテンツはビューによって提供されます。
各ビューは単純にPython関数として実装されています。
またDjangoではビューをリクエストされたURLから決定します。
URLからビューを得るには、Djangoは「URLconf」を使います。
from django.http import HttpResponse
def index(request):
return("Hello,world.You`re at athe polls index.")
# Create your views here.
def detail(request, question_id):
return HttpResponse("You`re looking at question %s." % question_id)
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You`re voting on question %s" % question_id)
このようにviewsを作ったとします。
これらのviewを{アプリ名}/urlsモジュールと結び付けます。
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
path(URLパターン,実行メソッド, nameタグ)の順で書きます。
これらはrootのurlから探索していきます。
こちらですね。
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
requstが来るとDjangoでは{プロジェクト名}/urls.pyのurlpatterns変数を探索 ⇒ pathのパターンマッチ⇒urlpatterns変数を探索⇒pathのパターンマッチ
という形でメソッドを実行します。
具体的に動作するビュー
各ビューには以下の二つの役割があります。
- ページのコンテンツを含むHttpResponseオブジェクトを返す
- Http404のような例外の送出
これら以外の処理はユーザ次第になります。
DjangoにとってはHttpResponseがあるか例外かだけです。
プロジェクトのテンプレート
{プロジェクト名}/setting.pyにはDjangoがどのようにテンプレートをロートして表示内容を整形する(レンダリング)するかがかかれています。
デフォルトの設定ファイルでは、DjnagoTemplatesバックエンドが設定されています。
そのAPP_DIRSがTRUEになっているとDjangoTemplatesはINSTALLED_APPSのそれぞれの"templates"サブディレクトリを検索するようになっています。
作成したアプリディレクトリでtemplatesというディレクトリを作成します。
次にtemplatesディレクトリを作成内で同じアプリ名
のディレクトリを作成し、さらにその中にindex.htmlというファイルを作成します。
公式のチュートリアルにあるようにアプリ名をpolls
とした場合は以下のようなディレクトリ構造になります。
polls/
└ templates/
└ polls/
└ index.html
これには以下の理由があります。
Djangoは名前がマッチした最初のテンプレートを使用する。
もし異なるアプリケーションの中に同じ名前のテンプレートがあった場合はDjnagoのはそれらを区別することができない。正しいテンプレートを取得する一番簡単な方法はそれらに名前空間を与えることである。
templateをビューに反映させる場合は以下のように記述します。
from django.http import HttpResponse
from django.template import loader
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html') # templateをロード
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request)) # コンテキストを渡す
ショートカット:render()
いちいちloaderやHttpResponseをimportするのってめんどくさいですよね。
そのようなあなたにはrenderメソッドおすすめです。
from django.shortcuts import render
とするだけでloaderもHttpResponseも使うことができます。
ショートカット:get_object_or_404()
get()を実行しオブジェクトが存在しない場合にHttp404を送出することは非常によく使われるやり方です。
from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
この`get_object_or_404'は
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Qeustion does not exit")
を省略した形になります。
URL間の名前空間
例えばpollsアプリはdetailビューを含むが、同じプロジェクトにブログのためにアプリがあり、そのアプリも同名のビューを含むかもしれないときに{% url %}テンプレートタブを
使ったときにdjangoはどのアプリのビューに対してurlを作成すればよいのだろうか?
Djnagoにそれを知らせるためにはURLconfに名前空間を追加することでできる。
{アプリ名}/urls.pyファイル内でapp_nameを追加してアプリケーションの名前空間を設定する。
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name='detail'),
path('<int:question_id>/results/', views.results, name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
ListViewとDetailView
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from .models import Choice, Question
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
def vote(request, question_id):
... # same as above, no changes needed.
ListViewは「オブジェクトのリストを表示する」および「あるタイプのオブジェクトの詳細ページを表示する」という二つの概念を抽象化するために使用します。
- 各汎用ビューは自分がどのモデルに対して動作するのかを知っておく必要がある。こではmodel属性を使用して提供される。
- DetailView汎用ビューには"pk"という名前でURLからプライマリーをキャプチャして渡すことになっている。
DetailView
デフォルトではDetailView汎用ビューは/_detail.htmlという名前のテンプレートを使用する。
temple_name属性を使用すると自動生成されたデフォルトのテンプレート名ではなく、指定したテンプレート名を使うようにDjangoに伝えることができる。
ListView
ListView汎用ビューは/_list.htmlというデフォルトのテンプレートを使うので、template_nameを使ってListViewに既存の"polls/index.html"テンプレートを使用するように伝えます。