Django+Reactで学ぶプログラミング基礎(14): Djangoチュートリアル(投票アプリその6)

##### [前回] [Django+Reactで学ぶプログラミング基礎(13): Djangoチュートリアル(投票アプリその5-4)](https://qiita.com/mingchun_zhao/items/86b81416e54597abf8df)

## はじめに

[Django公式チュートリアル](https://docs.djangoproject.com/ja/4.0/intro/tutorial01/)、その6です。
前回は、Django自動テストをしめくくりました。
今回は、アプリ構造をカスタマイズします。

## Djangoアプリ作成(その6): 投票(poll)アプリ

### 今回の内容

- Djangoの静的(static)ファイル
- アプリ構造のカスタマイズ
- 背景画像を追加

### Djangoの静的(static)ファイル

- 静的(static)ファイルとは
    - Webページのレンダリングに必要なファイル
        - HTML
        - 画像
        - JavaScript
        - CSS

- 複数アプリからなる大きなプロジェクトの場合
    - 各アプリが持っている静的ファイルの集まりを複数扱うのは煩雑な作業
    - 解決法: `django.contrib.staticfiles`
        - 静的ファイルを各アプリから(アプリ以外の場所からでもOK)、一つの場所に集め、運用環境で公開しやすくする

### アプリの構造をカスタマイズする手順

- 最初に、`polls`ディレクトリに、`static`ディレクトリを作成
    - Djangoはここから静的ファイルを探す
    - Djangoの`STATICFILES_FINDERS`
        - さまざまなソースから静的ファイルを検索してくれるファインダーのリスト
        - `AppDirectoriesFinder`は、デフォルトのファイダーの一つ
            - `settings.py`の`INSTALLED_APPS`に書かれた各アプリに対し、`static`サブディレクトリを検索してくれる
            ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/21c94086-a910-111a-6d00-e8c42becb597.png)
            - 管理サイトの静的ファイルも、同じディレクトリ構造
- `static`ディレクトリに`polls`という名前のディレクトリを作成
    - その中に`style.css`ファイルを作成
        - スタイルシートの場所は`polls/static/polls/style.css`
        - `AppDirectoriesFinder`のスタティックファイルファインダー機能により、`polls/style.css`として参照可能
```polls/static/polls/style.css
li a {
    color: green;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/94ca814d-d690-72c3-88dc-29cbedeae3e2.png)

- 作成したスタイルシートへのリンクをHTMLの上部に追加
    - `{% static %}`テンプレートタグは、静的ファイルの完全URLを生成
```polls/templates/polls/index.html
{% load static %}

<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}">
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/5e2ebac2-20f0-33c1-9098-520da4dc5fdf.png)

- VS Codeからサーバーを起動(すでに起動済みの場合は再起動)
```
C:\kanban\pollsite>..\venv\.venv\Scripts\activate
(venv) C:\kanban\pollsite>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
June 10, 2022 - 07:43:53
Django version 4.0.5, using settings 'pollsite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
```

- ブラウザで、`http://localhost:8000/polls/`にアクセス
    - 質問のリンクが緑色(Djangoのスタイル！)になる
        - スタイルシートが適切に読み込まれた証拠
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/7c314ef4-519b-4aeb-8393-447f89582b1f.png)

### 静的ファイルの名前空間

- Djangoは最初に見つけた静的ファイルの中から名前が一致するものを選ぶ
    - 複数アプリが存在する場合、Djangoに正しいものを指し示す必要あり
- 解決法: 名前空間を使用
    - 静的ファイルをアプリ自身の名前を付けたディレクトリの中に置く
        - `polls`サブディレクトリを作って配置する
        - 静的ファイルを直接`polls/static`に置かない

### 背景画像を追加

- 画像を配置するサブディレクトリを作成
    - `polls/static/polls/`ディレクトリの中に、`images`サブディレクトリを作成
    - `images`ディレクトリに、`background.png`という名前の画像を配置
        - 画像のパスは、`polls/static/polls/images/background.png`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/a393983a-7922-a554-47a9-f17ec61e7868.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/e8564c08-3c04-c545-fabe-cc29c43122dc.png)


- スタイルシートで背景画像を指定
```polls/static/polls/style.css
body {
    background: white url("images/background.png") no-repeat;
}
```

- ブラウザで、`http://localhost:8000/polls/`をリロード(F5)
    - 背景画像が読み込まれ、画面に表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/2a56cbfb-75ab-d109-7856-6a356daf532b.png)

### 注意事項

- 静的ファイルのリンクは、常に相対パスを使う
    - こうすることで、`static`テンプレートタグがURL生成で使用する`STATIC_URL`を自由に変更できる
- Djangoから生成されていない静的ファイルでは、テンプレートタグ`{% static %}`を使えない
    - 例えば、スタイルシート(上記`style.css`コードでも使用できず)

## おわりに

Webページをレンダリングする静的ファイルをカスタマイズしました。
次回も続きます。お楽しみに。

##### [次回] [Django+Reactで学ぶプログラミング基礎(15): Djangoチュートリアル(投票アプリその7-1)](https://qiita.com/mingchun_zhao/items/1bf35701c395e69697ad)