Django入門: ルートとビューの接続 ~ 簡単な一行掲示板アプリを作る その5【Windows10】
目次
- はじめに
- プロジェクトのurls.pyからアプリのurls.pyを参照する
- bbs\urls.pyの作成
- name='bbs_home'とは?
- bbs\views.pyの編集
- コードの検証
- 開発用サーバーによる動作確認
- /のルート情報を設定する
- おわりに
はじめに
この記事はDjangoで簡単な一行掲示板を作るシリーズ↓の記事です。
前回までにDjangoでプロジェクトとアプリを作成し、プロジェクトのurls.py
にアプリのurls.py
を指定する所までやりました。
今回からアプリのルート情報であるurls.py
を作成し、ルート情報とビューの接続をやっていきたいと思います。
この記事からDjangoのMVTの「V(View)」に触れることになります。
また、作業前のフォルダは例によってmanage.py
のあるフォルダに移動してください。
それから仮想環境がアクティベートされていることを確認してください。
アクティベートされていない場合はvenv\Scripts\activate
を実行してコマンドプロンプトで仮想環境をアクティベートしてください。
プロジェクトのurls.pyからアプリのurls.pyを参照する
manage.py
のあるフォルダからlinebbs
フォルダのurls.py
を参照すると現在は↓のようになっています。
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('bbs/', include('bbs.urls')), # <- ここに注目 ]
include()
関数の引数であるbbs.urls
は「bbs
アプリのurls.py
を参照する」という意味でした。
現在はこのbbs.urls
は定義されておらず、python manage.py check
を実行するとエラーになる状態です。
これから実際にbbs.urls
を定義します。
bbs\urls.pyの作成
manage.py
のあるフォルダから見たbbs\urls.py
を新規作成してください。
つまりbbs
アプリのフォルダ内にurls.py
を作成します。
bbs\urls.py
には↓のように記述します。
from django.urls import path from bbs.views import home_view # bbs\views.pyからhome_view関数をインポート urlpatterns = [ path('', home_view, name='bbs_home'), # ルートにhome_viewを指定 ]
↑でインポートしているビュー(home_view
)はまだ定義していません。
Djangoではビューは関数やクラスで定義します。それらの定義はアプリのフォルダにあるviews.py
ファイルかviews\
フォルダ以下に定義するのが一般的です。
あくまで一般的と言うだけであって他の場所にビューを定義することも可能です。
↑のhome_view
は、これからbbs\views.py
内に定義する予定です。
ですのでurls.py
には↑のようにインポートの記述を書いておきます。
urls.py
のルート情報とビューをどちらを先に定義するのかと言う話にもなりますが、今回のチュートリアルではトップダウン的に先にルート情報を定義しています。
それからurlpatterns
内の↓の記述についてです。
path('', home_view, name='bbs_home'), # ルートにhome_viewを指定
path()
に指定しているパスが空文字列になっています。
これはどういうことかというと、このように空文字を指定することでアプリのパスのルートを指定しています。
前回のlinebbs\urls.py
ではbbs\urls.py
に↓のように委譲していました。
path('bbs/', include('bbs.urls')),
↑これはbbs/
以下のパスをbbs.urls
に委譲するという意味です。
これはbbs.urls
内で定義するパスはbbs/
で始まるという意味になります。
つまりbbs\urls.py
に↓のようにパスを定義した場合、
path('brah/', brah_view, name='bbs_home'), # brah/ に brah_view を接続
↑のパスはhttps://localhost:8123/bbs/brah/
への解決になります。
プロジェクトのurls.py
で指定したbbs/
と、アプリのurls.py
で指定したbrah/
がくっついてるわけですね。
これがルート情報の委譲の仕組みです。
よって↓のようにパスを空文字にした場合、
path('', home_view, name='bbs_home'), # ルートにhome_viewを指定
パスはhttps://localhost:8123/bbs/
への解決になります。
ということはこれは、アプリのルート(bbs
アプリの/
, つまりbbs/
)への解決になるということですね。
name='bbs_home'とは?
↓のname='bbs_home'
ですが、
path('', home_view, name='bbs_home'), # ルートにhome_viewを指定
これはこのルートの名前です。
Djangoのルート情報には↑のように名前を付けることが出来ます。
この名前が必要になるケースですが、この名前はテンプレートファイル内から参照することが可能です。
Djangoのテンプレートファイルではパスを直書きするのではなく、↑のような名前を指定してパスを参照する仕組みが備わっています。
このようにすることでパスの変更を抽象化して、仕様変更につよいコードを書けるようになっているわけです。
bbs\views.pyの編集
では次にbbs\views.py
にhome_view()
関数を定義します。
これはパスbbs/
に接続するビューです。
manage.py
のあるフォルダからbbs\views.py
, つまりbbs
アプリのフォルダ内にviews.py
をエディタで編集します。
bbs\views.py
の内容は↓のようになっています。
from django.shortcuts import render # Create your views here.
コメントで「Create your views here.(ここにあなたのビューを作ってね)」と書かれていますね。
あとrender
という関数がインポートされています。
このrender
はテンプレートファイルを描画するための関数です。
よく使われるので最初から書かれているようです。
bbs\views.py
を↓のように編集します。
from django.shortcuts import render from django.http import HttpResponse # <- この行を追加 def home_view(request): """ パス bbs/ のテンプレートを出力するビュー """ return HttpResponse('Hello, World!') # テスト。レスポンスを返す
ビューではテンプレートファイルを描画するわけですが、今回はその前に簡単な「Hello, World!」をテンプレートファイルとは違う方法で出力してみます。
ここの「Hello, World!」でルート情報とビューの接続を確認し、確認が完了したらテンプレートファイルを定義すると言う風に進めます。
この方法は開発の分割統治で、問題を小さくするのに有効な方法でよく使われます。
(^ _ ^) | 無人島に持って行きたい分割統治 |
↑のコードを1つ1つ見ていきます。
まず↓のインポート文です。
from django.http import HttpResponse # <- この行を追加
django.http
モジュールからHttpResponse
クラスをインポートしています。
このHttpResponse
クラスはビューからの返り値、レスポンスを表現するクラスです。
HttpResponse
を使うとテンプレートファイルを書かずにビューからレスポンスを返すことが出来ます。
今回のような簡略的な「Hello, World!」を出力したい時などに便利なクラスです。
次に↓の部分、ビューの定義です。
def home_view(request): """ パス bbs/ のテンプレートを出力するビュー """ return HttpResponse('Hello, World!') # テスト。レスポンスを返す
先述の通りビューは関数かクラスで定義します。
↑のhome_view
は見ての通り関数です。
引数にrequest
を受け取っています。
このrequest
はルートからビューに渡されるリクエストで、これはユーザーの使っているブラウザから送信されたHTTPリクエストをDjangoのオブジェクトとして抽象化したものです。
request
オブジェクトにはパスやクエリ、それからHTTPリクエストのヘッダの内容などがデータとして格納されており、各種メソッドや属性を参照することでそれらのデータにアクセスできます。
つまり、ビューでURLのパラメーター、クエリを参照したい時や、リクエストがGET
メソッドかPOST
メソッドか知りたい時などは、このrequest
を参照すればいいことになります。
次にreturn HttpResponse('Hello, World!')
とやってビューからレスポンスを返しているところです。
HttpResponse
は第1引数にレスポンスの内容を指定します。↑の場合、その内容は「Hello, World!」になっています。
ビューの関数は返り値として↑のようにレスポンスを返します。
Djangoはこのレスポンスをビューから受け取って、描画(ブラウザにレスポンスを返す、正確にはWebサーバーが)します。
コードの検証
これでルートとビューの仮接続は完了しました。
↓のコマンドでコードに潜在的な問題が無いかチェックします。
> python manage.py check
特に問題が無ければ↓のように表示されます。
System check identified no issues (0 silenced).
開発用サーバーによる動作確認
↓のコードで開発用サーバーを起動します。
> python manage.py runserver 0.0.0.0:8123
↓のようなログが出力されプログラムが無限ループになります。
Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. September 19, 2020 - 19:40:15 Django version 3.1.1, using settings 'linebbs.settings' Starting development server at http://0.0.0.0:8123/ Quit the server with CTRL-BREAK.
ちなみにpython manage.py runserver
を実行する場合はpython manage.py check
を省略してもOKです。
python manage.py runserver
もコードの検証に失敗したらエラーを出力してくれるからです。
ブラウザのアドレスバーにhttp://localhost:8123/bbs/
と打ち込んでアクセスすると↓のように表示されます。
/のルート情報を設定する
今のままだと「http://localhost:8123/
」にアクセスした場合、ページが表示されません。
これの解決方法は色々あります。
ルート(/
)用のビューを作ったり、アプリのルート情報に委譲したりします。
今回のプロジェクトではルートはbbs
アプリのビューを指定したいと思います。
manage.py
のあるフォルダに移動し、エディタでlinebbs\urls.py
を開き↓のように編集します。
from django.contrib import admin from django.urls import path, include from bbs.views import home_view # <- この行を追加 urlpatterns = [ path('admin/', admin.site.urls), path('bbs/', include('bbs.urls')), path('', home_view, name='root'), # ←この行を追加 ]
↑のようにパス(''
)に今回作成したbbs
アプリのhome_view
を指定します。
これで「http://localhost:8123/
」にアクセスしたら、bbs
アプリのhome_view
が内容を描画するようになりました。
URLにアクセスすると「Hello, World!」と表示されます。
SEO的には「http://localhost:8123/
」と「http://localhost:8123/blog/
」の両方で同じページが表示されるので、/blog
の方のページにnoindex
を指定したほうが良いかもしれませんが、SEOについては今回は省略します。
おわりに
今回はルートとビューの仮接続を行いました。
次回からテンプレートファイルを作ってビューで描画してみたいと思います。
(・ v ・) | 次回はMVTのTに進むよ |