 
  こんにちはjunです。この記事はLaravel開発者がDjangoでアプリ作成の学習について解説しています。Laravelでいうこの機能はDjangoのここである、その逆はこうだと「Laravelとリンクさせて学習する」ことを重視しています。
前回は環境構築やアプリの概要、設定ファイルとディレクトリ構成の解説を行いました。今回の記事は
以上を行いたいと思います。
ではウェルカムページをカスタムのViewを表示することをやってみましょう。ちなみに、DjangoではMVTというコンセプトで作成され、LaravelのMVCとは少し意味合いが異なるそうです。見た目の部分はMVCではV(View)と定義しますが、MVTではT(Template)でありV(View)はリクエストを受け取り、レスポンスを定義します。
そのため今後はMVTに則り、見た目の部分の機能に関してはTemplateと呼ぶこととします。
テンプレートとは見た目(htmlレスポンス)を定義するファイルのことで.htmlで定義します。Laravelではresources/views/配下に~~.blade.phpというブレードを用いて見た目のhtmlを定義するのと同じです。
ソースのルートディレクトリにtemplates/ディレクトリ を作成し、base.htmlをさらに作成します。
├── db.sqlite3
├── djangodemo
├── manage.py
└── templates
    └── base.html
このソースルートのtemplatesはすべてのアプリで使用することができます。
base.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="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        <link rel="stylesheet" href="{% static 'style.css' %}">
        <title>test</title>
    </head>
    <body>
        <header>
            <nav class="navbar navbar-light bg-info">
                <div class="container">
                    <a class="navbar-brand" href="/">Navbar</a>
                </div>
            </nav>
        </header>
        <main class="d-block bg-light">
            <div class="container p-4 bg-white l-main-area">
                test
            </div>
        </main>
        <footer></footer>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    </body>
</html>
bootstrapを入れておきます。変数などは定義していませんが、ひとまずウェルカムページを上記の内容に書き換えましょう。
テンプレート作成したらdjangodemo/urls.pyを以下の様に変更します。
from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView # わすれずに
urlpatterns = [
    path('',TemplateView.as_view(template_name='base.html')), # これを追加
    path('admin/', admin.site.urls),
]
urls.pyはLaravelでいうroutes/配下のファイルであり、URLに対応する処理やテンプレートを指定する箇所です。上記の記述を用いて、http://localhost:8000/にアクセスした時に先ほどの、base.htmlを表示する様にしています。テンプレートを直接指定してレスポンスとして返すにはTemplateViewが必要です。
Laravel的には以下の様な記述です。
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    return view('base');
});
urls.pyを編集したらhttp://localhost:8000/にアクセスして以下の様な画面が表示されればひとまず、特定のURLにテンプレートを返すという感覚がわかると思います。
 
ひとまずカスタムテンプレートを表示できたのでDjangoで使用できる様々なディレクティブを解説します。
Viewからはテンプレートにはデータを渡すことができます。渡す時はDictで渡します。
from django.shortcuts import render
def index(request):
    context = {'value': 123}
    return render(request, 'polls/index.html', context)
そして変数を展開する時は{{ }} を用いて展開をします。値は自動的にエスケープ処理されます。ここはLaravelと同じですね。
<p>{{ value }}</p>
↓
<p>123</p>
for分は以下の様に使用します。
<!-- list = [{'name':'jun'},{'name':'apps'},{'name':'python'}] -->
<ul>
{% for item in list %}
<li>{{ item.name }}</li>
{% endfor %}
</ul>
↓
<ul>
<li>{{ item.jun }}</li>
<li>{{ item.apps }}</li>
<li>{{ item.python }}</li>
</ul>
Laravelでは @forディレクティブでしたね。ですが基本的に似ています。
if文は以下の様に使用します。
{% if user.is_authenticated%}
<li class="nav-item">
    <a class="nav-link" href="{% url 'logout' %}">ログアウト</a>
</li>
{% else %}
<li class="nav-item">
    <a class="nav-link active" aria-current="page" href="{% url 'login' %}">ログイン</a>
</li>
{% endif %}
Laravelでは @ifディレクティブでした。基本的に似ています。上記の例はユーザーのログイン状態で表示を分岐しています。
Laravelは{{ count($value) }} のように変数展開しつつもメソッドを使用することができます。しかし、Djangoの場合は内部にロジックを書くことができません。その代わりフィルタというものを使用して変数の値を変更します。
<!-- usersはリスト -->
<p>登録者数は{{ users|length }}人です。</p>
{{ 変数名|フィルタ名:<引数など>}}この様な入力規則になっています。
<p>作成日:{{ created_at|date:"Y年m月d日 H:s:i" }}</p>
上記の例はcreated_atを所定の日付フォーマットに変えるフィルタです。
使用可能なフィルタはこちらのドキュメントに記載されています。
Laravelでは route() というヘルパーを使用することでroutes/web.php などで定義した名前付きルートのURLを出力できます。Djangoにも似た様なものがあり、以下の様に表現します。
{% url "index" %}
またキーワード引数がある場合、例えばブログ記事の詳細を/blogs/1 のように示す場合route('blogs',['blog_id'=>1])のように引数を指定できます。Djangoも同様に
{% url "blogs" blog_id=1 %}
のように表示します。
リッチテキストを表示したい時などLaravelでは{!! !!}とすることでエスケープを解除していました。Djangoの場合は2通りあります。
1つはsafeフィルタを使う方法と、2つ目はエスケープ解除ディレクティブで囲むことです。
<div class="editor">
{{ value|safe }}
</div>
{% autoescape off %}
<div class="editor">
    {{ value }}
</div>
{% endautoescape %}
Laravelのテンプレートには @extends や@sectionをなどを用いて共通化を行うことができます。Djangoでも同じ様な方法で共通化が行えます。例えばbase.html に共通のヘッダやメニューなどを書いておき、任意のテンプレートに継承させてコンテンツだけ出力させることができます。
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>{% block title %}{% endblock  %}</title>
    </head>
    <body>
        <header>
            <!-- 省略 -->
        </header>
        <main>
            {% block content %}{% endblock  %}
        </main>
        <footer>
            <!-- 省略 -->
        </footer>
    </body>
</html>
base.htmlでは共通のヘッダーなどを定義しておきます。そして{% block content %}{% endblock  %}で子テンプレートで入力できる値を定義します。ここではタイトル(title)と内容(content)を入力できる様にします。
{% extends 'base.html' %}
{% block title %}詳細ページ{% endblock  %}
{% block content %}
<p> content </p>
{% endblock  %}
小テンプレート では上記の様に書くことで、親のbase.html に当てはめられた形でレンダリングされます。
プロジェクトで配置しておくcss,js,画像といった静的ファイルをLaraveで扱うときはpublic/ ディレクトリ配下にcss/,js/,images/などを配置して {{assets('/css/style.css')}} とすることで自動的にパスの解決をしてくれます。
Djangoで静的ファイルを利用するためには2つほど設定が必要です。
まずsetting.py にて静的ファイルを配置するディレクトリの設定を確認します。
コメント
コメント読み込み中..