久しぶりにDjangoで開発するときに復習として読む記事

# 0. 記事を書いたきっかけ
久しぶりにDjangoで開発するときに記憶喪失になっていたので、次回似たようなことがあったときの対策として復習用の記事としてまとめたものです。

python 3.8.12
django 3.2

内容としてはこちらの本を参考とさせていただいております。

https://www.amazon.co.jp/Django%E3%81%AE%E3%83%84%E3%83%9C%E3%81%A8%E3%82%B3%E3%83%84%E3%81%8C%E3%82%BC%E3%83%83%E3%82%BF%E3%82%A4%E3%81%AB%E3%82%8F%E3%81%8B%E3%82%8B%E6%9C%AC-%E5%A4%A7%E6%A9%8B-%E4%BA%AE%E5%A4%AA/dp/4798062219

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/1b0bca1b-c441-14b9-6b2d-c29a44ec6738.png)


# 1. Djangoの挙動の全体像
初めて学んだときの記事。

https://qiita.com/hosomatu/items/6a19c08a8946bc85189f

# 2. (おまけ)venvでの仮想環境構築
apt (パッケージマネージャ)の更新
```
sudo apt update
```
```
sudo apt upgrade
```

<br>
venv(仮想環境構築ツール)の導入

```
sudo apt install python3.8-venv
```

<br>

仮想環境の構築
-mでモジュールのパスの指定を省略。2回目のvenvは仮想環境名なので好きな名前でOK
```
python3 -m venv venv
```
これで、ルートディレクトリにvenvディレクトリが作成されるのでgitignoreしておく。
<br>


仮想環境の実行。venvディレクトリがあるディレクトリでコマンド実行。
```
source venv/bin/activate
```
ターミナルに(venv)表記が出たらOK




# 3. ディレクトリ構成
Djangoにて開発を行う際は、
- 全体を管轄する **「プロジェクト」**
- プロジェクトの中の各機能を担当する **「アプリケーション」**

の単位で開発を行なっていきます。

Djangoのインストール
```
pip install django==3.2
```

<br>

プロジェクトの開始
```
django-admin startproject hogeproject
```

<br>
アプリの開始(hogeprojectディレクトリにて実行)

```
python3 manage.py startapp book
```

> 仮想環境のpython3が呼び出されないと実行できないことがあります。asdfで導入したpython3にパスが通っている場合は、unalias python3 を実行して、which python3にて、hoge/venv/bin/python3 のようなパスで表示されるようにすれば実行できました。



<br>

一般的なディレクトリ構成の概要について説明


```python
root/ # ルートディレクトリ
├── book/ # アプリケーション
│   ├── __init__.py   # アプリケーションをPythonパッケージとして認識させるファイル
│   ├── admin.py # 管理サイトでデータモデルを管理するための設定を記述
│   ├── apps.py  # アプリケーションの設定を記述
│   ├── migrations/  # データベースマイグレーションファイルを格納
│   │   ├── __init__.py # migrationsディレクトリをPythonパッケージとして認識させるファイル
│   ├── models.py # データベースのモデルを定義
│   ├── tests.py  # アプリケーションの単体テストを記述
│   ├── views.py  # リクエストを処理し、レスポンスを返すビューを定義
├── project/ # プロジェクト
│   ├── __init__.py  # このディレクトリをPythonパッケージとして認識させるファイル
│   ├── asgi.py  # ASGI対応のエントリーポイント
│   ├── settings.py # プロジェクト全体の設定ファイル
│   ├── urls.py  # ルーティング設定のファイル。ここからアプリのurls.pyを呼び出す設定が必要
│   ├── wsgi.py # WSGI対応のエントリーポイント
├── db.sqlite3 # SQLiteデータベースファイル
├── manage.py  # Djangoプロジェクトを管理するためのコマンドラインユーティリティ

```

コマンドはルートディレクトリ(manage.pyが存在するディレクトリ）にて実行していきます


# 4. 管理画面の使用方法


管理ユーザーの作成
``` shell
python3 manage.py createsuperuser
```
<br>


サーバー起動

```
python3 manage.py runserver
```

ローカルサーバー/admin
にアクセス。最初に作成したユーザーでログインをすると管理画面に入ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/0f641ab7-50a0-5f2c-443b-fdc8ac6985a2.png)

各アプリケーションのadmin.pyにて使用するモデルをregisterしないとページに反映されないので注意

``` admin.py
# adminで該当のテーブルを確認するためにmodelを登録する必要がある。
from django.contrib import admin
from .models import SampleModel

admin.site.register(SampleModel)
```

# 5. [作業例]一覧ページ表示までの作業手順

### 1. book/urls.pyの更新
```book/urls.py
# プロジェクト全体のurls.pyから指定されているファイル
# パスに対して何を呼び出すかを定義

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view(), name='list-book') # パスを追加。class-based viewの書き方
    # path('', views.listbook_view, name='list-book'),  # function-basedの書き方
]
```

**path()関数**
第一引数がurlパス。第二引数がビュー関数など、マッチしたら呼び出されるもの。

https://docs.djangoproject.com/ja/5.1/ref/urls/


### 2. book/views.pyの更新
```book/views.py
# Viewクラスを定義。表示するテンプレートと使用するモデルを定義
from django.shortcuts import render
from django.views.generic import ListView
from .models import Book

class ListBookView(ListView) : #ListViewを継承。TemplateViewよりListに特化
    template_name = 'book/book_list.html' # テンプレートのパスを指定
    model = Book # 使用するモデルの指定

# def listbook_view(request) : # function-based の時は名前の通りクラスではなく関数を定義
    # object_list = Book.objects.all()

    ## renderメソッド。テンプレートをレンダリングしてレスポンスオブジェクトを作る関数。
    ## 第一引数のrequestは現在のリクエストオブジェクトを指定。第二引数でテンプレートファイルを指定。
    ## 第三引数でテンプレートに渡すコンテキスト（辞書形式のデータ)。先に定義したobject_list(右)を'object_list'(左)という名前で呼び出せるようにしている
    #return render(request, 'book/book_list.html', {'object_list': object_list})
```

### 3. book/models.pyにてBookモデルを定義。
```book/models.py
from django.db import models

# https://docs.djangoproject.com/ja/5.1/topics/db/models/
CATEGORY = (('business', 'ビジネス'), ('life', '生活'), ('other', 'その他'))

class Book(models.Model):
    title = models.CharField(max_length=100) # titleという名前のCharField(文字列型)のテーブルを定義。
    text = models.TextField(max_length=255)
    category = models.TextField(
        max_length=100,
        choices= CATEGORY # choicesオプション https://arc.net/l/quote/lehwmztf
    )

    def __str__(self): # 管理画面でオブジェクトをtitleの文字列で表示する
      return self.title

```


https://docs.djangoproject.com/ja/5.1/topics/db/models/

### テンプレートの作成
ListBookViewsで定義したパス(book/book_list.html)にテンプレートファイルを作成
```book/templates/book/book_list.html
<!-- object_listはListViewを使用しているときに提供されるコンテキスト変数。モデルの全データが渡される -->
{% for item in object_list %}
<ul>
  <li>{{ item.title }}</li>
  <li>{{ item.text }}</li>
  <li>{{ item.category }}</li>
</ul>
{% endfor %}
```

### マイグレーションの実行
プロジェクト全体でマイグレーションファイルを作成
```
python3 manage.py makemigrations
```

マイグレーションファイルからマイグレートを実行

```
python3 manage.py migrate
```

管理画面からデータを適当に登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/51c57c91-25fe-24e8-22e5-058bbdc32489.png)

### ローカルでの確認
ローカルサーバー起動
```
python3 manage.py runserver
```

ローカル/bookにアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/b87d9419-5fa3-ecca-738a-ebd192ad885c.png)


# 6. ドキュメント類
公式ドキュメント

https://docs.djangoproject.com/ja/5.1/


GitHub

https://github.com/django/django


Pythonの基本文法

https://pythonsoba.tech/python-basic/