(自分用)Django_1(基本のき/Hello World/テンプレート)

# 項目
1. Djangoプロジェクトを作る
2. サーバアドレスの指定
3. Djangoを動かしてみる
4. Hello World
5. テンプレート(html)呼び出し
6. テンプレートへpy側からデータ受け渡し

# 1.プロジェクトを作る
- プロジェクト = アプリケーションをまとめる単位
- APPの機能ごとにアプリケーションを作り、最後にそれを馬鹿でかいプロジェクトに纏めるとかが良いと思う
- 環境構築に関しては`Django_環境構築`みたいなのに後日書くかもしれんし書かないかもしれん

```bash:ターミナル
# 一回Djangoのバージョンだけ確認しておく
$ python -m django --version

# myappってプロジェクトを作る、startprojectって入れる事でプロジェクトの中身もある程度用意してくれる
$ django-admin startproject myapp
```
- これによって、自分が居たディレクトリの中に`myapp`ってディレクトリが出来ている
- `myapp`の中身
  - `manage.py`：このプロジェクトを動かしたり管理したりする時に使う、名前そのまま
  - `myapp(myappの中にもう１つmyappがある)`
     - `__init__.py`：このディレクトリでPythonを使うと宣言する
     - `asgi.py`：ASGI互換サーバに接続する際の基点になるらしい、よく分からない
     - `settings.py`：ここを編集する事でプロジェクトの設定を弄れる
     - `urls.py`：ここに接続した時、どの`def`を動かすかを決める
     - `wsgi.py`：WSGI互換サーバに接続する際の基点、全然分からない
- `startproject`によって上に書いた馬鹿でかいプロジェクトが作れる

# 2.サーバアドレスの指定
- サーバからどのアドレスに接続すれば良いかを教えてあげる

```python:settings.py
# ここを見つけ出して、自分のページのアドレスを入れる

# SECURITY WARNING: don't run with debug turned on in production!
# DEBUG = True

ALLOWED_HOSTS = ["自分のアドレス"]
```

# 3.Djangoを動かしてみる
```bash:ターミナル
# myappへ移動
$ cd myapp

# Djangoのサーバを動かす
$ python manage.py runserver
```
- `https://localhost:8000/`にアクセスして、ロケットが出てくれば成功
- 言うまでも無いが、実行終了は`Ctrl + c`

# 4.Hello World
- プロジェクト = アプリケーションが沢山集まったもの

```bash:ターミナル
# 上で作ったmyapp(馬鹿でかいプロジェクト)に移動
$ cd myapp

# myapp内にアプリーション作成、startappでアプリケーションを作るよと宣言
# 例に漏れず作ったアプリケーションの中に有る程度用意がされている
$ python manage.py startapp hello
```

```bash:myapp
myapp
┣━ hello
┣━ manage.py
┗━ myapp
```
- こんな感じのディレクトリが出来上がる
- `hello`の中身は取り敢えず`views.py`だけ意識すればOK
  - `views.py`はバックエンドの動きとかを書く場所、Flaskのpyファイルと同じ

```python:views.py
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse('Hello World')
```
- `index(request)`で、この関数が要求された時に`HttpResponse()`の中に入った値を返す
- `requestメソッド`されたら`HttpResponse`の中身を返すと覚えればOK

```python:myapp/myapp/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('hello/', include('hello.urls')),
    path('admin/', admin.site.urls),
]
```
- **プロジェクトのルーティング**
- このパスの時にどのアプリケーションを動かすかを設定する
- ここではリンクの末尾が`/hello`の時、`helloアプリケーション`を動かすよと言っている
- Djangoの動く流れ
  - プロジェクトのルーティング→アプリのルーティング(動かす関数を指定)→指定された動作が実行される
- `hello`の中に`urls.py`というファイルを作る

```python:myapp/hello/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
```
- **アプリケーションのルーティング**
- `path('', views.index, name='index'),`で、どのファイルのどの関数が、どの場合に動作するかを指示している
- `''`はアドレスを指定している、今回は何も無いので`/hello`で動く。<br>もし何か入れれば`/hello/~~`って感じのアドレスで動く。`<int：question_id>/`というものをここに入れる事も有るのだが、ちょい難しいので割愛
- `views.index`で`views`の`index`って関数を動かすよと宣言
- 一応その動きに`name='index'`ってやつで属性付けしておく

```python:myapp/myapp/settings.py
# ここを見つけて書き足す！
INSTALLED_APPS = [
    'hello.apps.HelloConfig', # これを付け足す！
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```
- どのクラスを参照するか設定している
- アプリケーション名が`bbs`なら`bbs.apps.BbsConfig`みたいな感じで書く
- この`BbsConfig`の所はアプリケーションの`apps.py`から`class ~~Config`ってなってる所をペーストする

```bash:ターミナル
# プロジェクトのディレクトリに戻って...
$ cd myapp

# Djangoを起動！
$ python manage.py runserver
```
- Flaskと比べると嫌になる程複雑だ...

# 5.テンプレート(html)呼び出し
```python:settings.py
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # <---DIRSの中身書き込む--->
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
        ],
        # <---ここまでの中身ね--->
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```

- テンプレート(html)を`views.py`から呼び出して使用する
- テンプレートは取り敢えずアプリケーション直下に`templates`ってディレクトリを作り、その中にアプリケーション名ディレクトリ作成、そして中にテンプレートの配置が良い
- Flaskと同じ様にtemplatesの中身にしか反応しないっぽい

```python:myapp/hello/views.py
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return render(request, 'hello/index.html')
```
- `return render()`の中にPATHを入れる事でhtmlを指定できる

```html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <p>Hello WoWWoW</p>
</body>
</html>
```
- `index.html`は取り敢えず普通に書いてもよろしい
- 実行結果で`Hello WoWWoW`と表示されれば完了

# 6.テンプレートへpy側からデータ受け渡し
```python:views.py
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    context = {
        'message': 'Hello World',
        'players': ['勇者', '戦士', '魔法使い', '忍者']
    }
    enemy = "スライム"
    return render(request, 'hello/index.html', context ,enemy)
```
- こんな感じで渡したいものを`return render()`の中に入れる
- 渡すものを`context ={ ~~ }`の様に纏め、`context`１つのみを`return`の所に入れる裏技がある

```html:(templates)/hello/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <p>{{ message }}</p>
        {% for player in players %}
            <p>{{ player }}はモンスターと戦った</p>
        {% endfor %}
    <p>{{ enemy }}</p>
</body>
</html>
```
- `{{ ~~ }}`に変数名を入れる事でpy側で書いた内容を渡せる
- Flaskでも書いたが、html側でpythonを使いたい時は`{% ~~ %}`で書く
- For文やif文の場合は`{% endfor %}`で締めなければならない
- ↑ここの詳しい解説はFlask_2,3あたりのテンプレートの項目が詳しいかも

# 7.終わりに
- Flaskと比べて面倒くさすぎる！