Djangoドキュメント作成2

今回は前回の記事の続きから説明します

前回の記事はこちら↓
https://qiita.com/rinto____/private/4b901e4f5eb61de81e21

## Djangoシェル

Djangoプロジェクトやアプリケーション内のコードを実行し、データベースへのアクセスや操作、モデルのテスト、開発中の機能のテストなどを行うことができます。

### 起動方法

全てターミナルで行います
プロジェクトフォルダ(django_app/)で

```
python manage.py shell
```

### print()
```
print("Hello")
```

### 終了方法

#### control + D を押した後 Enter で終了することができます

### データベース操作

プロジェクトフォルダ(django_app/)で

```
python manage.py shell
```

### インポート

```
from bbs.models import Article 
```

### 全件取得

```
Article.objects.all()
```

### 個別に取得

```
article = Article.objects.get(pk=1)
```

### 呼び出し

```
article.content
```

### データの追加

```
article = Article(content="お腹いっぱいです")
article.save()   #1行ずつ実行してください
```

""" 確認

```
Article.objects.all()
```

### データの編集

編集したいデータを取得

```
article = Article.objects.get(pk=4)
```

### 確認

```
article.content
```
### データの編集

```
article.content = "楽しかったです"
article.save()   #1行ずつ実行してください
```

### 確認

```
Article.objects.all()
```

### 削除

「楽しかったです」を削除

```
article.delete()
```

### 確認

```
Article.objects.all()
```

## Migration(マイグレーション)

Djangoにおけるマイグレーションは、データベーススキーマの変更を管理し、実際のデータベースに反映させるための仕組み
データベーススキーマとは、データベース内のテーブル、カラム、インデックスなどの構造を指す

## 手順

### モデルの変更

models.py ファイルで、データベーステーブルの構造に変更を加える操作（新しいフィールドの追加、既存フィールドの変更、テーブルの削除など）を行う

bbs/models.pyの編集
(user_nameを追加する)

```bbs > models.py
content = models.CharField(max_length=200)   #書いてある
user_name = models.CharField(max_length=100)   #この1行を追加する
```

### マイグレーションの作成

makemigrations コマンドを実行して、モデルの変更内容をマイグレーションファイルとして記録
（migrationsフォルダに新しいファイルが作られる）

#### ターミナルで

django_app/フォルダで

```
python manage.py makemigrations bbs
```

#### メッセージ

**2**と入力しEnterを押す

It is impossible to add a non-nullable field 'user_name' to article without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit and manually define a default value in models.py.
Select an option:

日本語にすると
「user_name」という非NULLフィールドを既存の「article」テーブルにデフォルト値なしで追加することはできません。これは、データベースが既存の行に対して何かしらの値を提供する必要があるためです。
以下から修正方法を選んでください：

1)デフォルト値を指定する（このカラムの既存のnull値の行すべてに設定されます）
2)中断し、models.pyで手動でデフォルト値を定義します。
オプションを選んでください：

### nullを許容する

bbs/models.pyの編集
(user_nameでnullを許容する)

```bbs > models.py
content = models.CharField(max_length=200)
    user_name = models.CharField(max_length=100, null=True)  #nullから追加する
```
#### ターミナル

django_app/フォルダで

```
python manage.py makemigrations bbs
```
これを行うことでmigrationsフォルダに新規ファイルが作成される

### マイグレーションの適用

ターミナルで

```
python manage.py migrate
```


### 確認

サーバー起動

```
python manage.py runserver
```

#### 以下URLへ

http://127.0.0.1:8000/admin/bbs/article/add/

![スクリーンショット 2024-12-26 17.22.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963683/bdb05a03-0bfa-a672-bc8a-acb74798d4d0.png)

### データを追加

![スクリーンショット 2024-12-26 17.24.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963683/a741d57b-8739-2bea-f22c-44377b9f89d8.png)

全ての投稿にUser nameをセットしましょう

### 追加したuser_nameを表示

index.htmlの編集

```index.html
<body>
  <h1>Hello Django</h1>
  <p>{{ message }}</p>

  {% for article in articles %}
    <p>{{ article }} <br><small>著者:{{ article.user_name }}</small>   <!-- articleの後から追加する -->
     <br> <a href='{% url "bbs:detail" article.id %}'>詳細</a>   <!-- 先頭にbrタグをつける -->
    </p>
    <hr>   <!-- hrタグをつける -->
  {% endfor %}
</body>
```

detail.htmlの編集

```detail.html
<body>
  <h1>Hello Django</h1>
  <p>{{ message }}</p>

  <p>{{ article.content }}</p>
  <p><small>著者:{{ article.user_name }}</small></p>   <!-- この1行を追加する -->
  <p><a href='{% url "bbs:index" %}'>一覧に戻る</a></p>
</body>
```

### 記事作成

アプリケーションからデータの追加

#### ルーティング

bbs/urls.pyの編集

```bbs > urls.py
app_name = 'bbs'

urlpatterns = [
  path('', views.index, name='index'),
  path('<int:id>', views.detail, name='detail'),
  path('create', views.create, name='create'),   #この1行を追加する
]
```

#### ビュー

bbs/views.pyでcreate関数を作る
今回は、固定値をデータベースに追加している

```bbs > views.py
def create(request):
    article = Article(content='追加したよ',user_name='わたし')
    article.save()

    articles = Article.objects.all()
    context = {'message': "Articleに追加",
                'articles': articles,
                }
    return render(request, 'bbs/index.html', context)
```

### 確認

http://127.0.0.1:8000/bbs/create

上のURLに飛ぶと下の画像のように「追加したよ」という新しいデータが作られる

![スクリーンショット 2024-12-26 17.48.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963683/79fe01bc-4eef-39ea-9648-bab109d468ae.png)

### index.htmlに新規作成ボタンを追加

```index.html
<body>
  <h1>Hello Django</h1>
  <p>{{ message }}</p>
<p>   <!-- ここのpタグを追加する -->
  <a href='{% url "bbs:create" %}'>新規作成</a>
</p>
  {% for article in articles %}
    <p>{{ article }} <br><small>著者:{{ article.user_name }}</small>
     <br> <a href='{% url "bbs:detail" article.id %}'>詳細</a>
    </p>
    <hr>
  {% endfor %}
</body>
```

新規作成ボタンをクリックすると、新しいデータベースに新しいデータが作られ記事一覧に表示される

### 記事削除

アプリケーションからデータを削除

#### ルーティング

bbs/urls.pyの編集

```bbs > urls.py
app_name = 'bbs'

urlpatterns = [
  path('', views.index, name='index'),
  path('<int:id>', views.detail, name='detail'),
  path('create', views.create, name='create'),
  path('<int:id>/delete', views.delete, name='delete'),  #この1行を追加する
]
```

#### ビュー

bbs/views.pyでdelete関数を作る

```bbs > views.py
def delete(request, id):
    article = get_object_or_404(Article, pk=id)
    article.delete()

    articles = Article.objects.all()
    context = {
        'message': 'ページID:'+ str(id) + 'を削除しました',
        'articles': articles,
    }
    return render(request, 'bbs/index.html', context)
```
### 動作確認

先ほどcreateした記事を削除(7は削除したい記事のID)

http://127.0.0.1:8000/bbs/7/delete

![スクリーンショット 2024-12-26 18.03.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963683/a91cdec4-1b63-a808-c75e-07fb61c66c55.png)

### 削除ボタンの追加

index.htmlの編集

```index.html
<body>
  <h1>Hello Django</h1>
  <p>{{ message }}</p>
<p>
  <a href='{% url "bbs:create" %}'>新規作成</a>
</p>
  {% for article in articles %}
    <p>{{ article }} <br><small>著者:{{ article.user_name }}</small>
     <br> <a href='{% url "bbs:detail" article.id %}'>詳細</a>
     <a href='{% url "bbs:delete" article.id %}'>削除</a>   <!-- この1行を追加する -->
    </p>
    <hr>
  {% endfor %}
</body>
```
![スクリーンショット 2024-12-26 18.06.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963683/71ed8934-a3cd-7bd8-0520-ce8aeea3ee26.png)

詳細ボタンの横に削除ボタンが追加される

## 共通部分のテンプレート

### 共通部分のテンプレート作成

index.htmlをコピーして「base.html」を作成
base.htmlのbodyの中の記述を削除
その後bodyの中に下記の記述をする

```base.html
<body>
{% block content %}
{% endblock %}
</body>
```

### 他のテンプレートでbase.htmlテンプレートを使用

index.htmlの編集
bodyの中身だけ残し削除
使用するテンプレートの指定→{% extends './base.html' %}
その後{% block content %}と{% endblock %}を追加する

```index.html
{% extends './base.html' %}
{% block content %}
<body>
    <h1>Hello Django</h1>
    <p>{{ message }}</p>
    <p>
        <a href='{% url "bbs:create" %}'>新規作成</a>
    </p>
    {% for article in articles %}
        <p>{{ article }}<br><small>著者:{{ article.user_name }}</small>
            <br><a href='{% url "bbs:detail" article.id %}'>詳細</a>
            <a href='{% url "bbs:delete" article.id %}'>削除</a>
        </p>
        <hr>
    {% endfor %}
</body>
{% endblock %}
```

### detail.htmlの編集

index.htmlで行ったことと同じように
bodyの中身だけ残し削除
使用するテンプレートの指定→{% extends './base.html' %}
その後{% block content %}と{% endblock %}を追加する

```detail.html
{% extends './base.html' %}
{% block content %}
<body>
    <h1>Hello Django</h1>
    <p>{{ message }}</p>

    <p>{{ article.content }}</p>
    <p><small>著者:{{ article.user_name }}</small></p>
    <p><a href='{% url "bbs:index" %}'>一覧に戻る</a></p>
</body>
{% endblock %}
```

### 確認
base.htmlの編集

```base.html
<title>bbs</title>
  <style>
    * {
      margin: 0;
    }
  </style>   <!-- styleタグを追加する -->
</head>
```

http://127.0.0.1:8000/bbs/
http://127.0.0.1:8000/bbs/1
上記のURLで確認してみましょう
見た目は変わっていないはずなのでエラーが起きないか確認しましょう

## Bootstrap

#### Bootstrapとは
ウェブアプリケーションやウェブサイトを開発する際に使用される、オープンソースのCSSおよびJavaScriptフレームワークのことです
これにより、デザインやレイアウトの作成が容易になります

### 読み込み

base.htmlの編集

```base.html
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- この下の1行を追加する -->
  <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'>
  <title>bbs</title>
</head>
```

### containerクラス作成

base.htmlの編集

```base.html
<body style="padding-top: 80px;">  <!-- sytleから追加する -->
  <div class="container">   <!-- この1行を追加する -->
    {% block content %}
    {% endblock %}
  </div>   <!-- ここでdivタグを閉じる -->
</body>
```

### navタグ設置

base.htmlの編集

```base.html
<body style="padding-top: 80px;">
<!-- この下の1行を追加する -->
<nav class='navbar navbar-expand-md navbar-dark bg-dark fixed-top'>
    <div class="container">
      <a class='navbar-brand' href='{% url "bbs:index" %}'>Django 掲示板</a>
    </div>   <!-- divタグの中身を書き換える -->
</nav>   <!-- ここでnavタグを閉じる -->
```

### body部分の見た目を整える

#### 最新記事を上（降順）に表示する

bbs/views.pyの編集

```bbs > views.py
def index(request):
    articles = Article.objects.all().order_by('-id')   #.orderから追加する

def create(request):
    article = Article(content='追加したよ',user_name='わたし')
    article.save()

    articles = Article.objects.all().order_by('-id')   #.orderから追加する

def delete(request, id):
    article = get_object_or_404(Article, pk=id)
    article.delete()

    articles = Article.objects.all().order_by('-id')   #.orderから追加する
```

### index.htmlでテーブルを作成

index.htmlの編集

```index.html
{% block content %}
<h1>Hello Django</h1>
<p>{{ message }}</p>
<p>
  <a href='{% url "bbs:create" %}'>新規作成</a>
</p>
<table class="table table-striped table-hover">   <!-- この1行を追加する -->
<!-- trタグを作り中身を追加する -->
  <tr>
    <th>Content</th>
    <th>User name</th>
    <th>Button</th>
  </tr>
  {% for article in articles %}
  <!-- この下からtrタグやtdタグをつけていく -->
  <tr>
    <td>{{ article.content }}</td>
    <td>{{ article.user_name }}</td>
    <td>
      <a href='{% url "bbs:detail" article.id %}'>詳細</a>
      <a href='{% url "bbs:delete" article.id %}'>削除</a>
    </td>
  </tr>

  {% endfor %}
</table>

{% endblock %}
```

### ボタン用のクラスを指定

index.htmlの編集

```index.html
 <a href='{% url "bbs:create" %}'  class="btn btn-primary">新規作成</a>   <!-- aタグの中にクラスをつける -->

<!-- 省略 -->
 <td>
      <a href='{% url "bbs:detail" article.id %}' class="btn btn-outline-primary">詳細</a>   <!-- aタグの中にクラスをつける -->
      <a href='{% url "bbs:delete" article.id %}' class="btn btn-outline-danger">削除</a>   <!-- aタグの中にクラスをつける -->
    </td>
```

detail.htmlの編集

```detail.html
<p><a href='{% url "bbs:index" %}' class="btn btn-outline-primary">一覧に戻る</a></p>   <!-- aタグの中にクラスをつける -->
```
### 確認
![スクリーンショット 2024-12-27 19.22.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963683/51aa7bb3-1afb-d17c-bb26-6a48aa5a4500.png)

このように降順に並び替えられ、テーブル型で整えられていればOK

今回はこれで終わりです。次回は検索フォーム作成から画像アップロードまでを解説しています。興味があればそちらも読んでみてください！

次回の記事↓
https://qiita.com/rinto____/private/3b84b54bfc4f05c51d1e