こんにちは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
にて静的ファイルを配置するディレクトリの設定を確認します。
コメント
コメント読み込み中..