[Django] URLの指定の仕方(URLディスパッチャ)

第三回になりました。
今回はDjangoのURLの指定の仕方を説明したいと思います。

シリーズ一覧

  1. プロジェクトの作成とアプリケーションの作成
  2. view関数の書き方
  3. URLの指定の仕方(URLディスパッチャ) <- 今回
  4. データベース(モデル)の設定
  5. 記事の投稿ページの作成
  6. 記事の一覧ページと詳細ページの追加
  7. 記事の編集ページと記事の削除機能の追加
  8. いいね機能の追加
  9. コメント機能の追加
  10. Bootstrapを利用したwebデザイン

はじめに

前回同様myblogという名前のプロジェクト
blogという名前のアプリを作成しいている呈で話を進めます。
現在のプロジェクトの構成は以下のようになっているとします。

./myblog
├── blog
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── templates
│   │   └── blog
│   │      └── index.html
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── manage.py
└── blog
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

また、blog/view.pyは以下の内容どちらかが書き込まれていることを想定しています。

関数ベースのビューの場合

from django.shortcuts import render

def index(request):
    template_name = "blog/index.html" # templates以下のパスを書く
    return render(request, template_name)

クラスベースのビューの場合

from django.views.generic import TemplateView

class index(TemplateView):
    template_name = "blog/index.html" # templates以下のパスを書く

URLってどこで設定するの?

DjangoでURLを指定するにはurls.pyを編集してあげる必要があります。
urls.pyに書かれているurlpatternsというリスト型の変数が実際にユーザーがアクセス出来るURLを表します。

URLを設定する

というわけで、実際に設定してみましょう。
トップページがhttp://localhost:8000/というURLになるように設定します。

./myblog/urls.pyがメインのURLを記述するところです。
今の状態は以下のようになっているはずです。

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

これを以下のように書き足します。

from django.contrib import admin
from django.urls import path, include # include を追記

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("blog.urls")),# 追記
]

続いて./blogディレクトリの中に、新しくurls.pyを作りましょう。

blog
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   └── __init__.py
├── templates
│   └── blog
│      └── index.html
├── models.py
├── tests.py
├── urls.py # 新しく作る
└── views.py

中身に以下の内容を書き込みます。

from django.urls import path
from . import views

urlpatterns = [
    path("" ,views.index,name="index"),
]

クラスベースの場合は以下のようにしてください。

from django.urls import path
from . import views
urlpatterns = [
  path("", views.index.as_view(), name="index") # クラスベースの場合は as_view メソッドを呼び出す
]

こうすることでhttp://localhot:8000というURLにアクセスすることができるようになります。

試しにやってみましょう。
コンソールで以下のコマンドを実行します。

python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).

You have 14 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.
November 09, 2018 - 17:28:42
Django version 2.0.8, using settings 'myblog.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

エラーが出なければ上記のような文字列が出力されます。
マイグレーションしてないよ、みたいなのが出ますが気にせずに
http://localhost:8000/

にアクセスしてみましょう。

アクセスに成功すればブラウザに

まい ぶろく とっぷぺーじ

と表示されるはずです。

今度は新しくhttp://localhost:8000/newというページを追加してみましょう。

新しいページを追加するにはblog/urls.py,blog/views.pyにそれぞれ追記します。

blog/urls.py

from django.urls import path
from . import views
urlpatterns = [
    path("", views.index, name="index"),
    path("new/", views.new, name="new"), # 追記
]

blog/views.py

from django.shortcuts import render

def index(request):
    # templates以下のパスを書く(アプリケーション名[blog] / ファイル名[index.html])
    template_name = "blog/index.html"
    return render(request, template_name)

def new(request): # 新しくnew関数を追記
    template_name = "blog/new.html"
    return render(request,template_name)

また、HTMLファイルも作っておきましょう。
blog/templates/blog/new.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>my-blog-new</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
  <p>まい ぶろぐ 新規記事の投稿ページ</p>
</body>

</html>

追記新規作成するファイルは以下の通りです。

blog
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   └── __init__.py
├── templates
│   └── blog
│      ├── index.html
│      └── new.html # 新しく作る
├── models.py
├── tests.py
├── urls.py # 追記するファイル
└── views.py # 追記するファイル

これでhttp://localhost:8000/new/にアクセスできるようになりますのでアクセスしてみましょう。

画面に

まい ぶろぐ 新規記事の投稿ページ

と表示されればOKです。

以下は新しく登場したpath関数とinclude関数の説明です。

path関数

path("new/", views.new, name="new"),

path関数の第一引数がURL、第二引数がそのURLに対応するview関数になります。
名前付き引数のnameがテンプレート内で指定するURLの名称です。※詳しくは次回以降説明します。
nameは省略できます。
省略するとview関数の名前がそのまま利用されますが、わかりづらいのできちんと設定しておくことをお勧めします。

クラスベースの場合は第二引数をviewクラスの名前にしてas_viewメソッドを呼び出します。

path("new/", views.new.as_view(), name="new"),

include関数

path関数の第二引数にview関数の代わりに指定する事でURLを連結することができます。

path("", include("blog.urls"))

上の例ではblog.urls.pyで設定したURLを連結させています。
blog/urls.pyで 以下のように設定されていれば

urlpatterns=[
    path("", views.index, name="index"),
    path("new/", views.new, name="new"),
]

実際にアクセスするURLはそれぞれ http://localhot:8000/ http://localhot:8000/new/ となります。

また、

path("blog/", include("blog.urls")) # "" -> "blog/"

とすると実際にアクセスするURLはそれぞれ http://localhot:8000/blog/ http://localhot:8000/blog/new/ となります。

/myblog/urls.pypath("blog/",include("blog.urls"))blog/urls.pyの内容を繋げています。

最後に

URLも設定できて、ページにアクセスできるようになったので、次回はデータベース(モデル)の設定をやってみましょう。

次回

[Django] データベース(モデル)の設定